package com.pactera.madp.cp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.pactera.madp.admin.api.constant.CrmDictTypeConstants;
import com.pactera.madp.admin.api.entity.SysDictItem;
import com.pactera.madp.cp.api.feign.RemoteDictService;
import com.pactera.madp.common.core.constant.SecurityConstants;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.common.core.util.R;
import com.pactera.madp.common.data.tenant.TenantContextHolder;
import com.pactera.madp.common.security.service.MadpUser;
import com.pactera.madp.common.security.util.SecurityUtils;
import com.pactera.madp.cp.api.bo.IndexMsgBO;
import com.pactera.madp.cp.api.dto.contact.*;
import com.pactera.madp.cp.api.dto.crm.CrmCustomQueryConditionDTO;
import com.pactera.madp.cp.api.dto.wxGZH.WxGZHDto;
import com.pactera.madp.cp.api.em.permission.ReqPerEnum;
import com.pactera.madp.cp.api.em.workcontact.AddWayEnum;
import com.pactera.madp.cp.api.em.workcontact.EventEnum;
import com.pactera.madp.cp.api.em.workmessage.MsgEnum;
import com.pactera.madp.cp.api.em.workupdatetime.TypeEnum;
import com.pactera.madp.cp.api.entity.*;
import com.pactera.madp.cp.api.entity.clientLossManagement.ContactLossEntity;
import com.pactera.madp.cp.api.entity.clientLossManagement.RemindCommunicationEntity;
import com.pactera.madp.cp.api.entity.crm.WorkAssetsInfoEntity;
import com.pactera.madp.cp.api.entity.crm.WorkCustomInfoEntity;
import com.pactera.madp.cp.api.entity.crm.WorkCustomInfoHisEntity;
import com.pactera.madp.cp.api.entity.employeeWechat.EmployeeDoEntity;
import com.pactera.madp.cp.api.entity.employeeWechat.EmployeeFollowEntity;
import com.pactera.madp.cp.api.entity.medium.MediumEnyity;
import com.pactera.madp.cp.api.entity.product.ProdContactEntity;
import com.pactera.madp.cp.api.entity.wm.WorkMsgEntity;
import com.pactera.madp.cp.api.feign.RemoteDeptService;
import com.pactera.madp.cp.api.model.transfer.GetContactRoom;
import com.pactera.madp.cp.api.model.workcontact.ContactData;
import com.pactera.madp.cp.api.model.workcontact.GetContactInfoResponse;
import com.pactera.madp.cp.api.model.workcontact.GetContactRequest;
import com.pactera.madp.cp.api.model.workcontact.LossContact;
import com.pactera.madp.cp.api.model.workcontacttag.GetContactTapModel;
import com.pactera.madp.cp.api.model.workcontacttag.GetEmployeeTagModel;
import com.pactera.madp.cp.api.page.SubPage;
import com.pactera.madp.cp.api.vo.ContactFieldPivotVO;
import com.pactera.madp.cp.api.vo.CustomerAssetsInfoVO;
import com.pactera.madp.cp.api.vo.ManagerViewCustomerVO;
import com.pactera.madp.cp.api.vo.contact.*;
import com.pactera.madp.cp.common.constant.Constant;
import com.pactera.madp.cp.common.util.DateUtils;
import com.pactera.madp.cp.common.util.FileUtils;
import com.pactera.madp.cp.common.util.PageUtil;
import com.pactera.madp.cp.common.util.WxApiUtils;
import com.pactera.madp.cp.common.util.file.FilesUtil;
import com.pactera.madp.cp.common.util.wm.WorkMsgHelper;
import com.pactera.madp.cp.config.WxAvatarUploadConfig;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.job.WorkMsgBackUpUtil;
import com.pactera.madp.cp.mapper.ContactEmployeeTrackMapper;
import com.pactera.madp.cp.mapper.ContactMapper;
import com.pactera.madp.cp.mapper.wm.WorkMsgMapper;
import com.pactera.madp.cp.service.*;
import com.vdurmont.emoji.EmojiParser;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.File;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.LongFunction;
import java.util.stream.Collectors;

import static com.pactera.madp.cp.common.util.DateHastListUtil.getDetHashList;
import static java.util.stream.Collectors.toList;

/**
 * @description: 客户实现类
 * @author: zhaojinjian
 * @create: 2020-11-26 15:07
 **/
@Service
@Slf4j
public class ContactServiceImpl extends ServiceImpl<ContactMapper, WorkContactEntity> implements IContactService {

    @Autowired
    private IContactLossService contactLossService;
    @Autowired
    private IContactService contactService;
    @Resource
    private ContactEmployeeTrackService contactEmployeeTrackService;
    @Autowired
    private IWorkEmployeeDepartmentService workEmployeeDepartmentService;
    @Autowired
    private RemoteDeptService remoteDeptService;
    @Autowired
    private IWorkUpdateTimeService updateTimeService;
    /**
     * 用户画像
     */
    @Autowired
    @Lazy
    private IWorkContactFieldPivotService contactFieldPivotService;
    @Autowired
    private IGreetingService greetingServiceImpl;
    @Autowired
    private IMediumService mediumService;
    @Autowired
    @Lazy
    private IWorkContactTagService contactTagService;
    @Autowired
    @Lazy
    private IWorkContactTagPivotService contactTagPivotService;
    @Autowired
    @Lazy
    private IWorkContactEmployeeService workContactEmployeeService;
    @Autowired
    private IWorkContactRoomService contactRoomService;
    @Autowired
    private IWorkEmployeeService workEmployeeService;
    @Autowired
    @Lazy
    private IExternalContactService externalContactService;
    @Autowired
    @Lazy
    private ICorpTagService corpTagService;
    @Autowired
    private ISendWelcomeMsgService sendWelcomeMsgService;
    @Autowired
    private IWorkRoomAutoPullService workRoomAutoPullService;
    @Autowired
    private ICorpService corpService;
    @Autowired
    private IWorkRoomService roomService;
    /**
     * 跟进记录对象
     */
    @Resource
    private EmployeeFollowService employeeFollowService;
    /**
     * 待办事项对象
     */
    @Resource
    @Lazy
    private EmployeeDoService employeeDoService;
    /**
     * @author: yangpengwei
     * @time: 2021/2/19 5:33 下午
     * @description 员工与客户的互动轨迹
     */
    @Resource
    private ContactEmployeeTrackMapper contactEmployeeTrackMapper;
    @Autowired
    private IChannelCodeService channelCodeService;
    @Autowired
    private IWorkEmployeeDepartmentService employeeDepartmentService;
    @Autowired
    private IWorkEmployeeService employeeService;
    @Autowired
    private IWorkContactService workContactService;
    @Autowired
    private IWorkCorpBlacklistService workCorpBlacklistService;
    @Autowired
    private ChannelCodeContactStatisticsService channelCodeContactStatisticsService;
    @Resource
    private WorkMsgMapper workMsgMapper;
    @Autowired
    private RemindCommunicationService remindCommunicationService;
    @Autowired
    private ProdContactService prodContactService;
    @Autowired
    private WxAvatarUploadConfig wxAvatarUploadConfig;
    @Autowired
    private WorkCustomInfoService workCustomInfoService;
    @Autowired
    private WorkAssetsInfoService workAssetsInfoService;
    @Autowired
    private IWorkContactRoomService workContactRoomService;
    /**
     * 远程调用字典信息
     */
    @Autowired
    private RemoteDictService remoteDictService;
    @Autowired
    private WorkContactEmployeeStaticsService contactEmployeeStaticsService;
    @Autowired
    private WxRedpackHandleService wxRedpackHandleService;

    @Override
    public Page<List<ContactData>> getContactPage(Page page, GetContactRequest param, int empId, int corpId, ReqPerEnum perEnum) {

        //region 如果客户持群数等于 0 而群聊数大于 0 返回空数据
        if (StringUtils.hasLength(param.getGroupNum()) && StringUtils.hasLength(param.getRoomId())) {
            String[] roomIds = param.getRoomId().split(",");
            if ("0".equals(param.getGroupNum()) && roomIds.length > 0) {
                return page;
            }
        }
        //endregion

        // 权限管理过滤
        List<WorkContactEmployeeEntity> contactEmployeeEntityList = getContactEmployeeListByEmpIdList(param, perEnum);
        if (contactEmployeeEntityList.isEmpty()) {
            return page;
        }

        List<Integer> contactEmployeeIdListResult = contactEmployeeEntityList.stream()
                .map(WorkContactEmployeeEntity::getId)
                .collect(toList());

        List<Integer> contactIdListResult = contactEmployeeEntityList.stream()
                .map(WorkContactEmployeeEntity::getContactId)
                .collect(toList());

        if (StringUtils.hasLength(param.getGroupNum()) || StringUtils.hasLength(param.getRoomId())) {
            contactIdListResult = getContactIdListByGroupNumAndRoomIds(contactIdListResult, param.getGroupNum(), param.getRoomId());
            if (contactIdListResult.isEmpty()) {
                return page;
            }
        }

        if (Objects.nonNull(param.getFieldId()) && param.getFieldId() > 0) {
            contactIdListResult = getContactIdListByField(contactIdListResult, param.getFieldId(), param.getFieldValue());
            if (contactIdListResult.isEmpty()) {
                return page;
            }
        }

        List<WorkContactEntity> contactEntityList = getContactEntityListByParam(param, corpId, contactIdListResult);

        if (contactEntityList.isEmpty()) {
            return page;
        }

        List<Integer> contactIdList = contactEntityList.stream()
                .map(WorkContactEntity::getId)
                .collect(toList());

        Map<Integer, WorkContactEntity> contactEntityMap = new HashMap<>(contactEntityList.size());
        for (WorkContactEntity entity : contactEntityList) {
            contactEntityMap.put(entity.getId(), entity);
        }

        List<WorkContactEmployeeEntity> workContactEmployeeEntities = workContactEmployeeService.lambdaQuery()
                .eq(WorkContactEmployeeEntity::getCorpId, corpId)
                .in(WorkContactEmployeeEntity::getContactId, contactIdList)
                .in(WorkContactEmployeeEntity::getId, contactEmployeeIdListResult).orderByDesc(BaseEntity::getCreateTime).list();


        Page<WorkContactEmployeeEntity> split = PageUtil.split(workContactEmployeeEntities, (int) page.getCurrent(), (int) page.getSize());

        List<WorkContactEmployeeEntity> entityList = split.getRecords();

        List<WorkContactRoomEntity> contactRoomEntityList = contactRoomService.lambdaQuery()
                .in(WorkContactRoomEntity::getContactId, contactIdList)
                .list();
        Map<Integer, List<Integer>> contactIdRoomIdListMap = new HashMap<>(contactIdList.size());
        List<Integer> roomIdList = new ArrayList<>();
        for (WorkContactRoomEntity entity : contactRoomEntityList) {
            roomIdList.add(entity.getRoomId());

            List<Integer> roomIds = contactIdRoomIdListMap.get(entity.getContactId());
            if (Objects.isNull(roomIds)) {
                roomIds = new ArrayList<>();
                contactIdRoomIdListMap.put(entity.getContactId(), roomIds);
            } else {
                roomIds.add(entity.getRoomId());
            }
        }

        Map<Integer, String> roomIdNameMap = new HashMap<>(roomIdList.size());
        if (!roomIdList.isEmpty()) {
            List<WorkRoomEntity> roomEntityList = roomService.lambdaQuery()
                    .select(WorkRoomEntity::getId, WorkRoomEntity::getName)
                    .in(WorkRoomEntity::getId, roomIdList)
                    .list();
            for (WorkRoomEntity entity : roomEntityList) {
                roomIdNameMap.put(entity.getId(), entity.getName());
            }
        }

        Map<Integer, Integer> contactEmpIdEmpIdMap = new HashMap<>(entityList.size());
        List<Integer> empIdList = new ArrayList<>();
        for (WorkContactEmployeeEntity entity : entityList) {
            empIdList.add(entity.getEmployeeId());
            contactEmpIdEmpIdMap.put(entity.getId(), entity.getEmployeeId());
        }
        List<WorkEmployeeEntity> employeeEntityList = (List<WorkEmployeeEntity>) employeeService.listByIds(empIdList);
        Map<Integer, String> empIdNameMap = new HashMap<>();
        for (WorkEmployeeEntity entity : employeeEntityList) {
            empIdNameMap.put(entity.getId(), entity.getName());
        }

        List<ContactData> voList = new ArrayList<>();
        for (WorkContactEmployeeEntity entity : entityList) {
            int cId = entity.getContactId();

            ContactData vo = new ContactData();
            vo.setId(entity.getId());

            WorkContactEntity contactEntity = contactEntityMap.get(cId);
            vo.setContactId(cId);
            vo.setAvatar(contactEntity.getAvatar());
            vo.setGender(contactEntity.getGender());
            if (contactEntity.getGender() == 0) {
                vo.setGenderText("未知");
            } else {
                vo.setGenderText(contactEntity.getGender() == 1 ? "男" : "女");
            }
            vo.setName(contactEntity.getName());
            vo.setBusinessNo(contactEntity.getBusinessNo());

            vo.setType(contactEntity.getType());
            vo.setTypeText(contactEntity.getType() == 1 ? "微信" : contactEntity.getCorpName() );

            vo.setRemark(entity.getRemark());
            vo.setAddWay(entity.getAddWay());
            vo.setAddWayText(AddWayEnum.getByCode(entity.getAddWay()));
            vo.setCreateTime(DateUtils.asString(entity.getCreateTime()));

            List<String> roomNameList = new ArrayList<>();
            List<Integer> roomIds = contactIdRoomIdListMap.get(cId);
            if (Objects.nonNull(roomIds)) {
                for (Integer roomId : roomIds) {
                    roomNameList.add(roomIdNameMap.get(roomId));
                }
            }
            vo.setRoomName(roomNameList);

            List<String> tagNameList = new ArrayList<>();
            List<WorkContactTagPivotEntity> list = contactTagPivotService.list(Wrappers.<WorkContactTagPivotEntity>lambdaQuery().eq(WorkContactTagPivotEntity::getContactId, entity.getContactId())
                    .eq(WorkContactTagPivotEntity::getEmployeeId, entity.getEmployeeId()));
            List<Integer> integers = new LinkedList<>();
            for (WorkContactTagPivotEntity f:list) {
                integers.add(f.getContactTagId());
            }
            if (!integers.isEmpty()){
                List<WorkContactTagEntity> entities = contactTagService.list(Wrappers.<WorkContactTagEntity>lambdaQuery()
                        .in(WorkContactTagEntity::getId, integers));
                for (WorkContactTagEntity e:entities) {
                    tagNameList.add(e.getName());
                }
            }

            vo.setTag(tagNameList);

            int eId = contactEmpIdEmpIdMap.get(entity.getId());
            vo.setEmployeeId(eId);
            vo.setEmployeeName(empIdNameMap.get(eId));
            vo.setIsContact(eId == empId ? 1 : 2);

            voList.add(vo);
        }

        String syncContactTime = updateTimeService.getLastUpdateTime(TypeEnum.CONTACT);
        SubPage subPage = new SubPage();
        subPage.setRecords(voList);
        subPage.setCurrent(page.getCurrent());
        subPage.setSize(page.getSize());
        subPage.setTotal(split.getTotal());
        subPage.getExtraProps().put("syncContactTime",syncContactTime);

        return subPage;
    }

    @Override
    public ContactMessageVxVO getContactInfoWx(String wxExternalUserid,String wxUserId) {
        ContactMessageVxVO contactMessageVxVO = new ContactMessageVxVO();
        WorkContactEntity contactEntity = externalContactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getCorpId,CorpContextHolder.getCorpId())
                .eq(WorkContactEntity::getWxExternalUserid, wxExternalUserid));
        if (contactEntity == null)
            return null;
        contactMessageVxVO.setGender(contactEntity.getGender());
        if (contactEntity.getGender() == 0){
            contactMessageVxVO.setGenderText("未知");
        }else {
            contactMessageVxVO.setGenderText(contactEntity.getGender() == 1 ? "男" : "女");
        }
        contactMessageVxVO.setType(contactEntity.getType());
        contactMessageVxVO.setTypeText(contactEntity.getType() == 1 ? "微信" : contactEntity.getCorpName() );
        contactMessageVxVO.setCorpName(contactEntity.getCorpName());
        contactMessageVxVO.setName(contactEntity.getName());
        contactMessageVxVO.setAvatar(contactEntity.getAvatar());
        contactMessageVxVO.setInBlacklist(contactEntity.getInBlacklist());

        WorkEmployeeEntity serviceOne = employeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery().eq(WorkEmployeeEntity::getWxUserId, wxUserId)
                .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(BaseEntity::getTenantId, TenantContextHolder.getTenantId()));

//        WorkContactEmployeeEntity one = workContactEmployeeService.getOne(Wrappers.<WorkContactEmployeeEntity>lambdaQuery()
//                .eq(WorkContactEmployeeEntity::getCorpId,CorpContextHolder.getCorpId())
//                .eq(WorkContactEmployeeEntity::getContactId, contactEntity.getId())
//                .eq(WorkContactEmployeeEntity::getEmployeeId,serviceOne.getId()));
        WorkContactEmployeeEntity one = workContactEmployeeService.getNewestRecordByContactIdAndEmployeeId(CorpContextHolder.getCorpId(), contactEntity.getId(), serviceOne.getId());
        if (one.getDelFlag().equals(1)){
//            ContactMessageVxVO vo = new ContactMessageVxVO();
//            vo.setIsContact(1);
//            return vo;
            contactMessageVxVO.setIsContact(1);
        }
        contactMessageVxVO.setDescription(one.getDescription());
        contactMessageVxVO.setRemark(one.getRemark());
        contactMessageVxVO.setEmployeeId(one.getEmployeeId());
        contactMessageVxVO.setPhone(JSONArray.parseArray(one.getRemarkMobiles()).isEmpty() ? "" : JSONArray.parseArray(one.getRemarkMobiles()).get(0).toString());

        WorkEmployeeEntity entity = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getCorpId,CorpContextHolder.getCorpId())
                .eq(WorkEmployeeEntity::getId, one.getEmployeeId())
                .eq(WorkEmployeeEntity::getCorpId, one.getCorpId()));

        List<GetContactTapModel> tags = contactTagService.getContactTapName(one.getEmployeeId(), one.getContactId());
        contactMessageVxVO.setTag(tags);

        contactMessageVxVO.setAddWay(one.getAddWay());
        contactMessageVxVO.setAddWayText(AddWayEnum.getByCode(one.getAddWay()));

        //关联CRM系统资产信息
        if (!JSONArray.parseArray(one.getRemarkMobiles()).isEmpty()) {
            String mobile = JSONArray.parseArray(one.getRemarkMobiles()).get(0).toString();
            CrmCustomQueryConditionDTO queryCondition = new CrmCustomQueryConditionDTO();
            queryCondition.setMobileTel(mobile);
            List<WorkCustomInfoEntity> workCustomInfoEntitys = workCustomInfoService.listByCondition(queryCondition);
            if (!workCustomInfoEntitys.isEmpty()) {
                CustomerAssetsInfoVO customerAssetsInfoVO = new CustomerAssetsInfoVO();
                List<WorkAssetsInfoEntity> workAssetsInfoEntities = workAssetsInfoService.listByCustNo(workCustomInfoEntitys.get(0).getCustNo());
                if (!workAssetsInfoEntities.isEmpty()) {
                    BeanUtil.copyProperties(workAssetsInfoEntities.get(0),customerAssetsInfoVO);
                }
                contactMessageVxVO.setCustomerAssetsInfoVO(customerAssetsInfoVO);
            }
        }

        String externalContactInfo = WxApiUtils.getExternalContactInfo(contactEntity.getCorpId(), wxExternalUserid);
        JSONObject jsonObject = JSONObject.parseObject(externalContactInfo);
        JSONArray followUser = jsonObject.getJSONArray("follow_user");
        List<ContactEmployeeVO> employeeVOS = new LinkedList<>();
        for (Object f:followUser) {
            JSONObject object = JSONObject.parseObject(String.valueOf(f));
            ContactEmployeeVO employeeVO = new ContactEmployeeVO();

            WorkEmployeeEntity userid = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId,CorpContextHolder.getCorpId())
                    .eq(WorkEmployeeEntity::getWxUserId, object.getString("userid")));
            CorpEntity corpEntity = corpService.getCorpInfoById(userid.getCorpId());

            employeeVO.setUserId(object.getString("userid"));
            employeeVO.setEmployeeId(userid.getId());
            employeeVO.setType(1);

            employeeVO.setEmployeeName(corpEntity.getCorpName() + "-" +userid.getName());
            employeeVO.setName(userid.getName());
            Long time = object.getLong("createtime") * 1000;
            DateTime of = DateTime.of(time);
            String datetime = of.toString("yyyy-MM-dd HH:mm:ss");
            employeeVO.setCreateTime(datetime);
            employeeVO.setAvatar(userid.getAvatar());

            if (object.get("userid").equals(entity.getWxUserId())){
                contactMessageVxVO.setCreateTime(datetime);
            }
            employeeVOS.add(employeeVO);
        }
        employeeVOS.sort(Comparator.comparing(ContactEmployeeVO::getCreateTime).reversed());
        contactMessageVxVO.setEmployeeList(employeeVOS);

        //获取客户所在群关联列表
        List<WorkContactRoomEntity> entities = contactRoomService.getBaseMapper().selectList(Wrappers.<WorkContactRoomEntity>lambdaQuery()
                .eq(WorkContactRoomEntity::getWxUserId, wxExternalUserid));
        List<ContactRoomVO> roomVOS = new LinkedList<>();
        //获取群信息
        for (WorkContactRoomEntity w:entities) {
            ContactRoomVO roomVO = new ContactRoomVO();
            roomVO.setJoinTime(DateTime.of(w.getJoinTime()).toString("yyyy-MM-dd HH:mm:ss"));
            WorkRoomEntity roomEntity = roomService.getOne(Wrappers.<WorkRoomEntity>lambdaQuery().eq(WorkRoomEntity::getId, w.getRoomId())
                    .eq(WorkRoomEntity::getRoomStatus,0));
            if (roomEntity == null){
                continue;
            }
            roomVO.setRoomName(roomEntity.getName());
            roomVO.setRoomId(roomEntity.getId());

            WorkEmployeeEntity employeeEntity = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId,CorpContextHolder.getCorpId())
                    .eq(WorkEmployeeEntity::getId, roomEntity.getOwnerId()));
            roomVO.setOwnerId(roomEntity.getOwnerId());
            CorpEntity corpEntity = corpService.getCorpInfoById(employeeEntity.getCorpId());
            roomVO.setOwnerName(corpEntity.getCorpName() + "-" + employeeEntity.getName());
            roomVO.setName(employeeEntity.getName());
            roomVO.setAvatar(employeeEntity.getAvatar());
            // 群成员数量统计
            List<WorkContactRoomEntity> contactRoomEntityList = contactRoomService.getWorkContactRoomsByRoomId(roomEntity.getId());
            // 群成员数量
            Integer memberNum = 0;
            // 今日入群数量
            if (contactRoomEntityList.size() > 0) {
                for (WorkContactRoomEntity workContactRoomEntity : contactRoomEntityList) {
                    if (workContactRoomEntity.getStatus().equals(1)) {
                        memberNum++;
                    }
                }
            }
            roomVO.setMemberNum(memberNum);

            roomVOS.add(roomVO);
        }
        roomVOS.sort(Comparator.comparing(ContactRoomVO::getJoinTime).reversed());
        contactMessageVxVO.setRoomList(roomVOS);

        List<ContactFieldPivotVO> list = contactFieldPivotService.getCrmContactFieldPivotList(contactEntity.getId(),serviceOne.getId());
        contactMessageVxVO.setContactFieldPivotList(list);

        contactMessageVxVO.setContactId(contactEntity.getId());
        log.info("contactMessageVxVO:   "+contactMessageVxVO);
        if (contactMessageVxVO.getInBlacklist().equals(1)){
            Integer corpId = CorpContextHolder.getCorpId();
            contactMessageVxVO.setReason(workCorpBlacklistService.getReason(corpId, contactEntity.getId()));
        }
        List<ProdContactEntity> contactProd = prodContactService.getContactProd(wxExternalUserid);
        ArrayList<ContactMessageVxVO.ProdList> prodLists = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(contactProd)){
            for (ProdContactEntity prodContactEntity : contactProd) {
                ContactMessageVxVO.ProdList prodList = new ContactMessageVxVO.ProdList();
                prodList.setProdName(prodContactEntity.getProdName());
                prodList.setOpening(prodContactEntity.getOpening());
                prodLists.add(prodList);
            }
        }
        contactMessageVxVO.setProdList(prodLists);
        contactMessageVxVO.setIsContact(0);
        return contactMessageVxVO;
    }

    @Override
    public ContactMessageVxVO getContactInfoWxDelete(String wxExternalUserid, String wxUserId) {
        ContactMessageVxVO contactMessageVxVO = new ContactMessageVxVO();
        WorkContactEntity contactEntity = externalContactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getCorpId,CorpContextHolder.getCorpId())
                .eq(WorkContactEntity::getWxExternalUserid, wxExternalUserid));
        contactMessageVxVO.setGender(contactEntity.getGender());
        if (contactEntity.getGender() == 0){
            contactMessageVxVO.setGenderText("未知");
        }else {
            contactMessageVxVO.setGenderText(contactEntity.getGender() == 1 ? "男" : "女");
        }
        contactMessageVxVO.setType(contactEntity.getType());
        contactMessageVxVO.setTypeText(contactEntity.getType() == 1 ? "微信" : contactEntity.getCorpName() );
        contactMessageVxVO.setCorpName(contactEntity.getCorpName());
        contactMessageVxVO.setName(contactEntity.getName());
        contactMessageVxVO.setAvatar(contactEntity.getAvatar());
        contactMessageVxVO.setInBlacklist(contactEntity.getInBlacklist());

        WorkEmployeeEntity serviceOne = employeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery().eq(WorkEmployeeEntity::getWxUserId, wxUserId)
                .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(BaseEntity::getTenantId, TenantContextHolder.getTenantId()));

        WorkContactEmployeeEntity one = workContactEmployeeService.getWorkContactEmployeeDel(CorpContextHolder.getCorpId(), contactEntity.getId(),serviceOne.getId());
        if (one == null){
            ContactMessageVxVO vo = new ContactMessageVxVO();
            vo.setIsContact(1);
            return vo;
        }
        contactMessageVxVO.setDescription(one.getDescription());
        contactMessageVxVO.setRemark(one.getRemark());
        contactMessageVxVO.setEmployeeId(one.getEmployeeId());

        WorkEmployeeEntity entity = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getCorpId,CorpContextHolder.getCorpId())
                .eq(WorkEmployeeEntity::getId, one.getEmployeeId())
                .eq(WorkEmployeeEntity::getCorpId, one.getCorpId()));

        List<GetContactTapModel> tags = contactTagService.getContactTapName(one.getEmployeeId(), one.getContactId());
        contactMessageVxVO.setTag(tags);

        contactMessageVxVO.setAddWay(one.getAddWay());
        contactMessageVxVO.setAddWayText(AddWayEnum.getByCode(one.getAddWay()));


        String externalContactInfo = WxApiUtils.getExternalContactInfo(contactEntity.getCorpId(), wxExternalUserid);
        JSONObject jsonObject = JSONObject.parseObject(externalContactInfo);
        JSONArray followUser = jsonObject.getJSONArray("follow_user");
        List<ContactEmployeeVO> employeeVOS = new LinkedList<>();
        for (Object f:followUser) {
            JSONObject object = JSONObject.parseObject(String.valueOf(f));
            ContactEmployeeVO employeeVO = new ContactEmployeeVO();

            WorkEmployeeEntity userid = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId,CorpContextHolder.getCorpId())
                    .eq(WorkEmployeeEntity::getWxUserId, object.getString("userid")));
            CorpEntity corpEntity = corpService.getCorpInfoById(userid.getCorpId());

            employeeVO.setUserId(object.getString("userid"));
            employeeVO.setEmployeeId(userid.getId());
            employeeVO.setType(1);

            employeeVO.setEmployeeName(corpEntity.getCorpName() + "-" +userid.getName());
            employeeVO.setName(userid.getName());
            Long time = object.getLong("createtime") * 1000;
            DateTime of = DateTime.of(time);
            String datetime = of.toString("yyyy-MM-dd HH:mm:ss");
            employeeVO.setCreateTime(datetime);
            employeeVO.setAvatar(userid.getAvatar());

            if (object.get("userid").equals(entity.getWxUserId())){
                contactMessageVxVO.setCreateTime(datetime);
            }
            employeeVOS.add(employeeVO);
        }
        contactMessageVxVO.setEmployeeList(employeeVOS);

        List<WorkContactRoomEntity> entities = contactRoomService.getBaseMapper().selectList(Wrappers.<WorkContactRoomEntity>lambdaQuery()
                .eq(WorkContactRoomEntity::getWxUserId, wxExternalUserid));
        List<ContactRoomVO> roomVOS = new LinkedList<>();
        //获取群信息
        for (WorkContactRoomEntity w:entities) {
            ContactRoomVO roomVO = new ContactRoomVO();
            roomVO.setJoinTime(DateTime.of(w.getJoinTime()).toString("yyyy-MM-dd HH:mm:ss"));
            WorkRoomEntity roomEntity = roomService.getOne(Wrappers.<WorkRoomEntity>lambdaQuery().eq(WorkRoomEntity::getId, w.getRoomId())
                    .eq(WorkRoomEntity::getRoomStatus,0));
            if (roomEntity == null){
                continue;
            }
            roomVO.setRoomName(roomEntity.getName());
            roomVO.setRoomId(roomEntity.getId());

            WorkEmployeeEntity employeeEntity = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId,CorpContextHolder.getCorpId())
                    .eq(WorkEmployeeEntity::getId, roomEntity.getOwnerId()));
            roomVO.setOwnerId(roomEntity.getOwnerId());
            CorpEntity corpEntity = corpService.getCorpInfoById(employeeEntity.getCorpId());
            roomVO.setOwnerName(corpEntity.getCorpName() + "-" + employeeEntity.getName());
            roomVO.setName(employeeEntity.getName());
            roomVO.setAvatar(employeeEntity.getAvatar());
            // 群成员数量统计
            List<WorkContactRoomEntity> contactRoomEntityList = contactRoomService.getWorkContactRoomsByRoomId(roomEntity.getId());
            // 群成员数量
            Integer memberNum = 0;
            // 今日入群数量
            if (contactRoomEntityList.size() > 0) {
                for (WorkContactRoomEntity workContactRoomEntity : contactRoomEntityList) {
                    if (workContactRoomEntity.getStatus().equals(1)) {
                        memberNum++;
                    }
                }
            }
            roomVO.setMemberNum(memberNum);

            roomVOS.add(roomVO);
        }
        contactMessageVxVO.setRoomList(roomVOS);

        List<ContactFieldPivotVO> list = contactFieldPivotService.getCrmContactFieldPivotList(contactEntity.getId(),serviceOne.getId());
        contactMessageVxVO.setContactFieldPivotList(list);

        for (ContactFieldPivotVO c:list) {
            if (c.getName().equals("手机号")){
                contactMessageVxVO.setPhone(String.valueOf(c.getValue()));
            }
        }
        contactMessageVxVO.setContactId(contactEntity.getId());
        log.info("contactMessageVxVO:   "+contactMessageVxVO);
        if (contactMessageVxVO.getInBlacklist().equals(1)){
            Integer corpId = CorpContextHolder.getCorpId();
            contactMessageVxVO.setReason(workCorpBlacklistService.getReason(corpId, contactEntity.getId()));
        }
        contactMessageVxVO.setIsContact(0);
        return contactMessageVxVO;
    }

    /**
     * @author: yangpengwei
     * @time: 2021/3/17 11:19 上午
     * @description 权限管理查询条件配置
     */
    private List<Integer> getPermissionEmpIdList(ReqPerEnum permission) {
        if (permission == ReqPerEnum.ALL) {
            return employeeService.lambdaQuery()
                    .select(WorkEmployeeEntity::getId)
                    .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                    .list()
                    .stream()
                    .map(WorkEmployeeEntity::getId)
                    .collect(toList());
        }

        if (permission == ReqPerEnum.DEPARTMENT) {
            // 查询员工所属的部门 id 列表
            return employeeDepartmentService.getDeptAndChildDeptEmpIdList();
        }

        if (permission == ReqPerEnum.EMPLOYEE) {
            return Arrays.asList(AccountService.getEmpId());
        }

        return Collections.emptyList();
    }

    private List<Integer> getContactIdListByGroupNumAndRoomIds(List<Integer> contactIdList, String groupNum, String roomIds) {
        if (!StringUtils.hasLength(groupNum)) {
            groupNum = "3";
        }
        List<WorkRoomEntity> list = roomService.list(Wrappers.<WorkRoomEntity>lambdaQuery()
                .eq(WorkRoomEntity::getRoomStatus, 1));


        if (StringUtils.hasLength(roomIds)) {
            // 根据 roomIds 过滤客户
            List<String> roomIdList = Arrays.asList(roomIds.split(","));
            // 在群里的客户
            List<Integer> contactIdListHas = new LinkedList<>();
            if (list.isEmpty()){
                contactIdListHas = contactRoomService.lambdaQuery()
                        .select(WorkContactRoomEntity::getContactId)
                        .groupBy(WorkContactRoomEntity::getContactId)
                        .in(WorkContactRoomEntity::getRoomId, roomIdList)
                        .in(WorkContactRoomEntity::getContactId, contactIdList)
                        .list()
                        .stream()
                        .map(WorkContactRoomEntity::getContactId)
                        .collect(toList());
            }else {
                contactIdListHas = contactRoomService.lambdaQuery()
                        .select(WorkContactRoomEntity::getContactId)
                        .groupBy(WorkContactRoomEntity::getContactId)
                        .notIn(WorkContactRoomEntity::getRoomId,list.stream().map(WorkRoomEntity::getId).collect(toList()))
                        .in(WorkContactRoomEntity::getRoomId, roomIdList)
                        .in(WorkContactRoomEntity::getContactId, contactIdList)
                        .list()
                        .stream()
                        .map(WorkContactRoomEntity::getContactId)
                        .collect(toList());
            }


            if ("1".equals(groupNum)) {
                // 只有一个群的客户
                List<Integer> contactIdListResult = new LinkedList<>();
                if (list.isEmpty()){
                    contactIdListResult = contactRoomService.lambdaQuery()
                            .select(WorkContactRoomEntity::getContactId)
                            .groupBy(WorkContactRoomEntity::getContactId)
                            .in(WorkContactRoomEntity::getContactId, contactIdList)
                            .having("count(contact_id) = 1")
                            .list()
                            .stream()
                            .map(WorkContactRoomEntity::getContactId)
                            .collect(toList());
                }else {
                    contactIdListResult = contactRoomService.lambdaQuery()
                            .select(WorkContactRoomEntity::getContactId)
                            .groupBy(WorkContactRoomEntity::getContactId)
                            .notIn(WorkContactRoomEntity::getRoomId,list.stream().map(WorkRoomEntity::getId).collect(toList()))
                            .in(WorkContactRoomEntity::getContactId, contactIdList)
                            .having("count(contact_id) = 1")
                            .list()
                            .stream()
                            .map(WorkContactRoomEntity::getContactId)
                            .collect(toList());
                }

                // 交集
                contactIdListResult.retainAll(contactIdListHas);
                return contactIdListResult;
            }

            if ("2".equals(groupNum)) {
                // 只有一个群的客户
                List<Integer> contactIdListResult = new LinkedList<>();
                if (list.isEmpty()){
                    contactIdListResult = contactRoomService.lambdaQuery()
                            .select(WorkContactRoomEntity::getContactId)
                            .groupBy(WorkContactRoomEntity::getContactId)
                            .in(WorkContactRoomEntity::getContactId, contactIdList)
                            .having("count(contact_id) > 1")
                            .list()
                            .stream()
                            .map(WorkContactRoomEntity::getContactId)
                            .collect(toList());
                }else {
                    contactIdListResult = contactRoomService.lambdaQuery()
                            .select(WorkContactRoomEntity::getContactId)
                            .groupBy(WorkContactRoomEntity::getContactId)
                            .notIn(WorkContactRoomEntity::getRoomId,list.stream().map(WorkRoomEntity::getId).collect(toList()))
                            .in(WorkContactRoomEntity::getContactId, contactIdList)
                            .having("count(contact_id) > 1")
                            .list()
                            .stream()
                            .map(WorkContactRoomEntity::getContactId)
                            .collect(toList());
                }

                // 交集
                contactIdListResult.retainAll(contactIdListHas);
                return contactIdListResult;
            }

            // 在群内的客户
            return contactIdListHas;
        } else {
            // 获取所有没有群的客户
            if ("0".equals(groupNum)) {
                // 查出所有群
                List<Integer> roomIdList = roomService.lambdaQuery()
                        .select(WorkRoomEntity::getId)
                        .eq(WorkRoomEntity::getCorpId, CorpContextHolder.getCorpId())
                        .eq(WorkRoomEntity::getRoomStatus,0)
                        .list()
                        .stream()
                        .map(WorkRoomEntity::getId)
                        .collect(toList());

                // 查出所有客户
                List<Integer> contactIdListResult = lambdaQuery()
                        .select(WorkContactEntity::getId)
                        .eq(WorkContactEntity::getCorpId, CorpContextHolder.getCorpId())
                        .in(WorkContactEntity::getId, contactIdList)
                        .list()
                        .stream()
                        .map(WorkContactEntity::getId)
                        .collect(toList());

                // 没有客户群直接返回所有客户
                if (roomIdList.isEmpty()) {
                    return contactIdListResult;
                }
                List<Integer> contactIdListHasRoom = new LinkedList<>();

                // 查出所有有群的客户
                if (list.isEmpty()){
                    contactIdListHasRoom = contactRoomService.lambdaQuery()
                            .select(WorkContactRoomEntity::getContactId)
                            .in(WorkContactRoomEntity::getRoomId, roomIdList)
                            .in(WorkContactRoomEntity::getContactId, contactIdList)
                            .groupBy(WorkContactRoomEntity::getContactId)
                            .list()
                            .stream()
                            .map(WorkContactRoomEntity::getContactId)
                            .collect(toList());
                }else {
                    contactIdListHasRoom = contactRoomService.lambdaQuery()
                            .select(WorkContactRoomEntity::getContactId)
                            .notIn(WorkContactRoomEntity::getRoomId,list.stream().map(WorkRoomEntity::getId).collect(toList()))
                            .in(WorkContactRoomEntity::getRoomId, roomIdList)
                            .in(WorkContactRoomEntity::getContactId, contactIdList)
                            .groupBy(WorkContactRoomEntity::getContactId)
                            .list()
                            .stream()
                            .map(WorkContactRoomEntity::getContactId)
                            .collect(toList());
                }

                contactIdListResult.removeAll(contactIdListHasRoom);

                return contactIdListResult;
            }

            // 获取只有 1 个群的客户
            if ("1".equals(groupNum)) {
                if (list.isEmpty()){
                    return contactRoomService.lambdaQuery()
                            .select(WorkContactRoomEntity::getContactId)
                            .groupBy(WorkContactRoomEntity::getContactId)
                            .in(WorkContactRoomEntity::getContactId, contactIdList)
                            .having("count(contact_id) = 1")
                            .list()
                            .stream()
                            .map(WorkContactRoomEntity::getContactId)
                            .collect(toList());
                }else {
                    return contactRoomService.lambdaQuery()
                            .select(WorkContactRoomEntity::getContactId)
                            .groupBy(WorkContactRoomEntity::getContactId)
                            .notIn(WorkContactRoomEntity::getRoomId,list.stream().map(WorkRoomEntity::getId).collect(toList()))
                            .in(WorkContactRoomEntity::getContactId, contactIdList)
                            .having("count(contact_id) = 1")
                            .list()
                            .stream()
                            .map(WorkContactRoomEntity::getContactId)
                            .collect(toList());
                }

            }

            // 获取有多个群的客户
            if ("2".equals(groupNum)) {
                if (list.isEmpty()){
                    return contactRoomService.lambdaQuery()
                            .select(WorkContactRoomEntity::getContactId)
                            .groupBy(WorkContactRoomEntity::getContactId)
                            .in(WorkContactRoomEntity::getContactId, contactIdList)
                            .having("count(contact_id) > 1")
                            .list()
                            .stream()
                            .map(WorkContactRoomEntity::getContactId)
                            .collect(toList());
                }else {
                    return contactRoomService.lambdaQuery()
                        .select(WorkContactRoomEntity::getContactId)
                        .groupBy(WorkContactRoomEntity::getContactId)
                        .notIn(WorkContactRoomEntity::getRoomId,list.stream().map(WorkRoomEntity::getId).collect(toList()))
                        .in(WorkContactRoomEntity::getContactId, contactIdList)
                        .having("count(contact_id) > 1")
                        .list()
                        .stream()
                        .map(WorkContactRoomEntity::getContactId)
                        .collect(toList());

                }

            }

            // 查出所有客户
            return lambdaQuery()
                    .select(WorkContactEntity::getId)
                    .eq(WorkContactEntity::getCorpId, CorpContextHolder.getCorpId())
                    .in(WorkContactEntity::getId, contactIdList)
                    .list()
                    .stream().map(WorkContactEntity::getId)
                    .collect(toList());
        }
    }

    private List<Integer> getContactIdListByField(List<Integer> contactIdList, int fieldId, String fieldValue) {
        if (fieldId == 0) {
            return contactFieldPivotService.lambdaQuery()
                    .select(ContactFieldPivotEntity::getContactId)
                    .in(ContactFieldPivotEntity::getContactId, contactIdList)
                    .list()
                    .stream()
                    .map(ContactFieldPivotEntity::getContactId)
                    .collect(toList());
        }

        if (!StringUtils.hasLength(fieldValue)) {
            return Collections.emptyList();
        }

        return contactFieldPivotService.lambdaQuery()
                .select(ContactFieldPivotEntity::getContactId)
                .eq(ContactFieldPivotEntity::getContactFieldId, fieldId)
                .in(ContactFieldPivotEntity::getContactId, contactIdList)
                .like(ContactFieldPivotEntity::getValue, fieldValue)
                .list()
                .stream()
                .map(ContactFieldPivotEntity::getContactId)
                .collect(toList());
    }

    private List<WorkContactEmployeeEntity> getContactEmployeeListByEmpIdList(GetContactRequest param, ReqPerEnum perEnum) {
        List<Integer> empIdList = getPermissionEmpIdList(perEnum);

        String empIds = param.getEmployeeId();
        if (StringUtils.hasLength(empIds)) {
            List<String> strings = Arrays.asList(empIds.split(","));
            List<Integer> codesInteger = strings.stream().map(Integer::parseInt).collect(toList());
            empIdList.retainAll(codesInteger);
        }

        if (empIdList.isEmpty()) {
            return Collections.emptyList();
        }

        LambdaQueryChainWrapper<WorkContactEmployeeEntity> wrapper = workContactEmployeeService.lambdaQuery()
                .select(WorkContactEmployeeEntity::getId, WorkContactEmployeeEntity::getContactId)
                .in(WorkContactEmployeeEntity::getEmployeeId, empIdList);

        String remark = param.getRemark();
        if (StringUtils.hasLength(remark)) {
            wrapper.like(WorkContactEmployeeEntity::getRemark, remark);
        }

        String addWay = param.getAddWay();
        if (StringUtils.hasLength(addWay)) {
            wrapper.eq(WorkContactEmployeeEntity::getAddWay, addWay);
        }

        if (StringUtils.hasLength(param.getStartTime())) {
            wrapper.ge(WorkContactEmployeeEntity::getCreateTime, param.getStartTime()+" 00:00:00");
        }
        if (StringUtils.hasLength(param.getEndTime())) {
            wrapper.le(WorkContactEmployeeEntity::getCreateTime, param.getEndTime()+" 23:59:59");
        }

        return wrapper.list();
    }

    private List<WorkContactEntity> getContactEntityListByParam(GetContactRequest param, int corpId, List<Integer> contactIdList) {
        if (contactIdList.isEmpty()) {
            return Collections.emptyList();
        }

        LambdaQueryChainWrapper<WorkContactEntity> wrapper = lambdaQuery();
        wrapper.eq(WorkContactEntity::getCorpId, corpId);
        wrapper.in(WorkContactEntity::getId, contactIdList);
        if (StringUtils.hasLength(param.getKeyWords())) {
            wrapper.and(i -> {
                        i.like(WorkContactEntity::getName, param.getKeyWords())
                                .or()
                                .like(WorkContactEntity::getNickName, param.getKeyWords());
                    }
            );
        }
        if (Objects.nonNull(param.getGender()) && param.getGender() < 3) {
            wrapper.eq(WorkContactEntity::getGender, param.getGender());
        }
        if (StringUtils.hasLength(param.getBusinessNo())) {
            wrapper.like(WorkContactEntity::getBusinessNo, param.getBusinessNo());
        }
        return wrapper.list();
    }

    private List<ContactData> pageContactList(List<ContactData> list, Integer pageNum, Integer pageSize) {
        if (list != null && list.size() > 0) {
            Integer count = list.size(); // 记录总数
            Integer pageCount = 0; // 页数
            if (count % pageSize == 0) {
                pageCount = count / pageSize;
            } else {
                pageCount = count / pageSize + 1;
            }
            int fromIndex = 0; // 开始索引
            int toIndex = 0; // 结束索引

            if (pageNum != pageCount) {
                fromIndex = (pageNum - 1) * pageSize;
                toIndex = fromIndex + pageSize;
            } else {
                fromIndex = (pageNum - 1) * pageSize;
                toIndex = count;
            }
            return list.subList(fromIndex, toIndex);
        }
        return null;
    }

    /**
     * @description 获取客户详情
     * @author zhaojinjian
     * @createTime 2020/12/6 11:22
     */
    @Override
    public GetContactInfoResponse getContactInfo(Integer contactId, Integer empId, Integer corpId) {
        GetContactInfoResponse contactInfoResponse = new GetContactInfoResponse();

        //region 客户信息数据

        WorkContactEntity workContact = this.baseMapper.selectById(contactId);
        contactInfoResponse.setBusinessNo(workContact.getBusinessNo());
        contactInfoResponse.setName(workContact.getName());
        contactInfoResponse.setGender(workContact.getGender());
        contactInfoResponse.setAvatar(workContact.getAvatar());
        //endregion

        //region 获取客户的群

        List<Integer> contactIds = new ArrayList<>();
        contactIds.add(contactId);
        List<GetContactRoom> contactRooms = contactRoomService.getBaseMapper().getContactRoomList(contactIds, null);
        String ss[] = new String[contactRooms.size()];
        for (int i = 0; i < contactRooms.size(); i++) {
            ss[i] = contactRooms.get(i).getRoomName();
        }
        contactInfoResponse.setRoomName(ss);

        //region 获取客户的标签
        List<GetContactTapModel> tags = contactTagService.getContactTapName(empId, contactId);
        contactInfoResponse.setTag(tags);
        //endregion

        //region 客户通讯录中间表数据
        WorkContactEmployeeEntity workContactEmployee = workContactEmployeeService.getWorkContactEmployeeInfo(corpId, empId, contactId);
        contactInfoResponse.setRemark(workContactEmployee.getRemark());
        contactInfoResponse.setDescription(workContactEmployee.getDescription());
        contactInfoResponse.setAddWay(workContactEmployee.getAddWay());
        contactInfoResponse.setAddWAyText(AddWayEnum.getByCode(workContactEmployee.getAddWay()));
        contactInfoResponse.setType(workContact.getType());
        contactInfoResponse.setTypeText(workContact.getType() == 1 ? "微信用户" :workContact.getCorpName());
//        List<Integer> empIds = workContactEmployeeService.getBelongToEmployeeId(contactId, corpId);
        List<Integer> empIds = new LinkedList<>();
        empIds.add(empId);

        //endregion

        //region 通讯录 企业
        if (empIds != null && empIds.size() > 0) {
            String[] empName = workEmployeeService.getEmployeeName(empIds);
            CorpEntity corpEntity = corpService.getCorpInfoById(corpId);
            empName = Arrays.stream(empName).map(value -> corpEntity.getCorpName() + "--" + value).toArray(String[]::new);
            contactInfoResponse.setEmployeeName(empName);
        } else {
            contactInfoResponse.setEmployeeName(new String[0]);
        }
        //endregion
        return contactInfoResponse;
    }

    @Override
    public String getWXExternalUserid(int contactId) {
        WorkContactEntity workContactEntity = this.baseMapper.selectById(contactId);
        if (workContactEntity != null) {
            return workContactEntity.getWxExternalUserid();
        }
        return "";
    }

    /**
     * @description 根据微信外部联系人id获取当前客户的本地id
     * @author zhaojinjian
     * @createTime 2020/12/17 15:35
     */
    @Override
    public Integer getContactId(String wxExternalUserid,Integer corpId) {
        QueryWrapper<WorkContactEntity> contactWrapper = new QueryWrapper<>();
        contactWrapper.select("id");
        contactWrapper.eq("wx_external_userid", wxExternalUserid);
        contactWrapper.eq("corp_id", corpId);
        WorkContactEntity contactEntity = this.baseMapper.selectOne(contactWrapper);
        if (contactEntity == null) {
            return null;
        } else {
            return contactEntity.getId();
        }
    }

    /**
     * @description 修改客户编号
     * @author zhaojinjian
     * @createTime 2020/12/6 11:22
     */
    @Override
    public boolean updateBusinessNo(Integer empId, Integer contactId, String businessNo) {
        WorkContactEntity entity = new WorkContactEntity();
        entity.setId(contactId);
        entity.setBusinessNo(businessNo);

//        if (result) {
//            saveTrack(empId, contactId, EventEnum.INFO, EventEnum.INFO.getMsg() + ": 客户编号",1);
//        }
        return updateById(entity);
    }

    /**
     * @description 客户 - 修改客户详情基本信息
     * @author zhaojinjian
     * @createTime 2020/12/28 10:41
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateContact(UpdateContactDto parem, Integer corpId, Integer empId) {
        if (parem.getContactId() != null) {
            if (!StrUtil.isBlank(parem.getBusinessNo())) {
                WorkContactEntity one = getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                        .eq(WorkContactEntity::getCorpId, corpId)
                        .eq(WorkContactEntity::getBusinessNo,parem.getBusinessNo())
                        .ne(WorkContactEntity::getId,parem.getContactId()));
                if (one != null){
                    throw new CheckedException("当前编号重复");
                }
                updateBusinessNo(empId, parem.getContactId(), parem.getBusinessNo());
            }else {
                updateBusinessNo(empId,parem.getContactId(),"");
            }
            if (parem.getTag() != null ) {
                contactTagPivotService.updateContactTapPivot(empId, parem.getContactId(), parem.getTag());
            }
            if (parem.getDescription() != null  || parem.getRemark() != null ) {
                workContactEmployeeService.updateRemarkOrDescription(corpId, empId, parem.getContactId(), parem.getRemark(), parem.getDescription());
            }
            return true;
        }
        throw new CheckedException("非法的参数");
    }

    @Override
    public boolean insertAllContact(List<WorkContactEntity> contacts) {
        return this.saveBatch(contacts);
    }

    /**
     * @description 添加企业的客户（存在则修改）
     * @author zhaojinjian
     * @createTime 2020/12/19 11:04
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertAllContact(List<WorkContactEntity> contacts, Integer corpId) {
        boolean result = false;
        QueryWrapper<WorkContactEntity> contactWrapper = new QueryWrapper<>();
        contactWrapper.select("wx_external_userid,id");
        contactWrapper.eq("corp_id", corpId);
//        contactWrapper.isNull("deleted_at");
        List<WorkContactEntity> contactList = this.list(contactWrapper);

        List<WorkContactEntity> diffContactList = contacts.stream().filter(item -> !contactList.stream().map(e -> e.getWxExternalUserid()).collect(toList()).contains(item.getWxExternalUserid())).collect(toList());
        log.info("diffContactList="+diffContactList);
        contacts.removeAll(diffContactList);
        log.info("contacts="+contacts);
        contacts.forEach(item -> {
            Optional<WorkContactEntity> contactOp = contactList.stream().filter(c -> c.getWxExternalUserid().equals(item.getWxExternalUserid())).findAny();
            WorkContactEntity model = contactOp.get();
            if (model != null) {
                item.setBusinessNo(model.getBusinessNo());
                item.setInBlacklist(model.getInBlacklist());
                item.setId(model.getId());
            }
        });
        if (diffContactList != null && diffContactList.size() > 0) {
            //result = this.saveBatch(diffContactList);
            int result1 = 0;
            for (WorkContactEntity workContactEntity:
                    diffContactList) {
                workContactEntity.setName(EmojiParser.parseToAliases(workContactEntity.getName()));
                log.info("workContactEntity="+workContactEntity);
                result1 = this.baseMapper.insert(workContactEntity);
            }
            if(result1 > 0){
                result = true;
            }
        }
        if (contacts != null && contacts.size() > 0) {
            int result2  = 0;
            for (WorkContactEntity workContactEntity:
                    contacts) {
                workContactEntity.setName(EmojiParser.parseToAliases(workContactEntity.getName()));
                result2 = this.baseMapper.updateById(workContactEntity);
            }
            if(result2 > 0){
                result = true;
            }
        }
        return result;
    }

    @Override
    public boolean insertContact(WorkContactEntity contact) {
        QueryWrapper<WorkContactEntity> contactWrapper = new QueryWrapper<>();
        contactWrapper.eq("wx_external_userid", contact.getWxExternalUserid());
//        contactWrapper.isNull("deleted_at");
        WorkContactEntity resultContact = this.baseMapper.selectOne(contactWrapper);
        if (resultContact != null) {
            resultContact.setPosition(contact.getPosition());
            resultContact.setName(contact.getName());
            resultContact.setGender(contact.getGender());
            resultContact.setCorpName(contact.getCorpName());
            resultContact.setCorpFullName(contact.getCorpFullName());
            resultContact.setExternalProfile(contact.getExternalProfile());
            contact.setId(resultContact.getId());
            return this.updateById(resultContact);
        }
        return this.baseMapper.insert(contact) == 1;
    }

    /**
     * @description 同步客户时，添加客户信息
     * @author zhaojinjian
     * @createTime 2020/12/17 11:07
     */
    @Override
    public Integer insertWXSynContact(JSONObject contactJson, Integer corpId) {
        //region 客户信息赋值

        WorkContactEntity contact = new WorkContactEntity();
        contact.setAvatar(contactJson.getString("avatar"));
        contact.setName(contactJson.getString("name"));
        contact.setUnionid(contactJson.getString("unionid"));
        contact.setPosition(contactJson.getString("position"));
        contact.setWxExternalUserid(contactJson.getString("external_userid"));
        contact.setType(contactJson.getInteger("type"));
        contact.setGender(contactJson.getInteger("gender"));
        contact.setCorpFullName(contactJson.getString("corp_full_name"));
        contact.setCorpName(contactJson.getString("corp_name"));
        contact.setExternalProfile(contactJson.getString("external_profile"));
        contact.setCreateTime(LocalDateTime.now());
        contact.setCorpId(corpId);
        contact.setBusinessNo("");
        contact.setFollowUpStatus(0);
        contact.setNickName("");
        insertContact(contact);
        return contact.getId();
        //endregion
    }

    /**saveTrack
     * @description 同步客户
     * @author zhaojinjian
     * @createTime 2020/12/12 11:43
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean synContact(Integer corpId) {
        //获取当前企业下所有成员的微信UserId
        Map<String, Integer> empIdAndUserId = workEmployeeService.getCorpByUserId(corpId);
        List<String> wx_UserIds = empIdAndUserId.keySet().stream().collect(toList());

        Map<String, Integer> tagIds = contactTagService.getContactTagId(corpId);
        //根据成员微信id获取当前成员下客户列表
        JSONArray array = externalContactService.getAllExternalUserId(wx_UserIds, corpId);
        List<Object> arrayList = Arrays.stream(array.toArray()).distinct().collect(toList());
        //根据成员微信id数组，获取多个微信客户详细信息
        Map<String, JSONObject> list = externalContactService.getExternalContactMap(arrayList, corpId);
        //处理多个微信客户详细信息本地化
        Map<WorkContactEntity, Map<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>>> modelMap = externalContactToWorkContact(list, corpId, null);

        List<WorkContactEntity> contactList = modelMap.keySet().stream().collect(toList());

        boolean result = insertAllContact(contactList, corpId);

        if (result) {
            List<WorkContactEmployeeEntity> contactEmployeeList = new ArrayList<>();
            List<WorkContactTagPivotEntity> contactTagPivotList = new ArrayList<>();
            for (Map.Entry<WorkContactEntity, Map<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>>> entry : modelMap.entrySet()) {
                for (Map.Entry<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>> aa : entry.getValue().entrySet()) {
                    Integer empId = empIdAndUserId.get(aa.getKey());
                    for (Map.Entry<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>> bb : aa.getValue().entrySet()) {
                        WorkContactEmployeeEntity contactEmployeeEntity = new WorkContactEmployeeEntity();
                        Gson gson = new Gson();
                        contactEmployeeEntity = gson.fromJson(gson.toJson(bb.getKey()), WorkContactEmployeeEntity.class);
                        contactEmployeeEntity.setContactId(entry.getKey().getId());
                        contactEmployeeEntity.setEmployeeId(empId);
                        List<WorkContactEmployeeEntity> lossContact = workContactEmployeeService.getLossContact(corpId, contactEmployeeEntity.getContactId(), contactEmployeeEntity.getEmployeeId());
                        if (!lossContact.isEmpty()){
                            long time = DateUtils.asDate(lossContact.get(0).getCreateTime()).getTime();
                            long time1 = DateUtils.asDate(contactEmployeeEntity.getCreateTime()).getTime();
                            if (time1 <= time){
                                continue;
                            }
//                            if (contactEmployeeEntity.getCreateTime().equals(lossContact.get(0).getCreateTime())){
//                                continue;
//                            }
                        }
//                        contactEmployeeEntity.setCreateTime();
                        if (Objects.nonNull(tagIds) && !tagIds.isEmpty()) {
                            for (Map.Entry<String, WorkContactTagPivotEntity> cc : bb.getValue().entrySet()) {
                                cc.getValue().setContactId(entry.getKey().getId());
                                cc.getValue().setEmployeeId(empId);
                                cc.getValue().setContactTagId(tagIds.get(cc.getKey()));
                                contactTagPivotList.add(cc.getValue());
                            }
                        }
                        contactEmployeeList.add(contactEmployeeEntity);
                    }
                }
            }
            if (contactTagPivotList != null && contactTagPivotList.size() > 0) {
                result = contactTagPivotService.insertAllTagPivot(contactTagPivotList);
            }
            if (contactEmployeeList != null && contactEmployeeList.size() > 0) {
                result = workContactEmployeeService.insertAllContactEmployee(contactEmployeeList,1);
            }
            updateTimeService.updateSynTime(corpId,TypeEnum.CONTACT);
            return result;
        }
        return result;
    }

    /**
     * @description 同步客户时，对微信返回的客户详情数据做处理
     * @author zhaojinjian
     * @createTime 2020/12/19 14:41
     * @Param list-多个微信客户详情（key-外部联系人的userid,value-请求微信客户详情接口返回的数据），corpid-哪个企业的客户，userId-如果指定跟进成员，则在创建客户成员表实体时过滤掉其他跟进成员的信息，若为空，则创建当前客户所有跟进成员的中间表信息
     */
    private Map<WorkContactEntity, Map<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>>> externalContactToWorkContact(Map<String, JSONObject> list, Integer corpId, String userId) {
        if (!list.isEmpty()) {
            log.info("list为："+list);
            Map<WorkContactEntity, Map<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>>> contactBelongEmployee = new HashMap<>();
            Map<String, String> cotactAvatarPathMap = new HashMap<>();
            //region 遍历企业微信的客户详情信息，转成本地库实体
            for (Map.Entry<String, JSONObject> mapEntry : list.entrySet()) {
                JSONObject json = mapEntry.getValue();
                if (json.getInteger("errcode") == 0) {
                    JSONObject contactJson = json.getJSONObject("external_contact");
                    String contactAvatar = FileUtils.getContactAvatarPath();
                    //添加同步时，微信客户信息 返回客户id
                    WorkContactEntity contact = new WorkContactEntity();
                    if (!StrUtil.isBlank(contactJson.getString("avatar"))) {
                        if (!cotactAvatarPathMap.containsKey(contactJson.getString("avatar"))) {
                            cotactAvatarPathMap.put(contactJson.getString("avatar"), contactAvatar);
                            contact.setAvatar(wxAvatarUploadConfig.getEnabled() ? FilesUtil.getFileURI(contactAvatar) : contactJson.getString("avatar"));
                        } else {
                            //如果key已存在，则用户头像路径取key对应的value
                            contact.setAvatar(FilesUtil.getFileURI(cotactAvatarPathMap.get(contactJson.getString("avatar"))));
                        }
                    } else {
                        contact.setAvatar("");
                    }
                    contact.setName(contactJson.getString("name"));
                    contact.setUnionid(contactJson.getString("unionid"));
                    contact.setPosition(contactJson.getString("position"));
                    contact.setWxExternalUserid(contactJson.getString("external_userid"));
                    contact.setType(contactJson.getInteger("type"));
                    contact.setGender(contactJson.getInteger("gender"));
                    contact.setCorpFullName(contactJson.getString("corp_full_name"));
                    contact.setCorpName(contactJson.getString("corp_name"));
                    contact.setExternalProfile(contactJson.getString("external_profile"));
                    contact.setCorpId(corpId);
                    contact.setBusinessNo("");
                    contact.setFollowUpStatus(0);
                    contact.setNickName("");

                    Map<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>> contactEmployeeMap = new HashMap<>();

                    JSONArray followUser = json.getJSONArray("follow_user");

                    for (int i = 0; i < followUser.size(); i++) {
                        Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>> employeeToTag = new HashMap<>();
                        JSONObject followUserItem = followUser.getJSONObject(i);

                        //region 如果成员id存在，则只能获取当前成员的信息

                        if (userId != null && !userId.isEmpty()) {
                            if (!followUserItem.getString("userid").equals(userId)) {
                                continue;
                            }
                        }
                        //endregion

                        //region 客户员工中间表数据赋值
                        WorkContactEmployeeEntity contactEmployee = new WorkContactEmployeeEntity();
                        contactEmployee.setRemark(followUserItem.getString("remark"));
                        contactEmployee.setDescription(followUserItem.getString("description"));
                        Long time = followUserItem.getLong("createtime") * 1000;
                        DateTime of = DateTime.of(time);
                        String datetime = of.toString("yyyy-MM-dd HH:mm:ss");
                        contactEmployee.setCreateTime(DateUtils.asLocalDateTime(datetime));
//                        contactEmployee.setCreateTime(DateUtils.asLocalDateTime(new Date(followUserItem.getLong("createtime"))));
                        contactEmployee.setRemarkCorpName(followUserItem.getString("remark_corp_name"));
                        contactEmployee.setRemarkMobiles(followUserItem.getString("remark_mobiles"));
                        contactEmployee.setAddWay(followUserItem.getInteger("add_way"));
                        contactEmployee.setOperUserid(followUserItem.getString("oper_userid"));
                        contactEmployee.setState(followUserItem.getString("state"));
                        // contactEmployee.setContactId(contactId);
                        contactEmployee.setCorpId(corpId);
                        //contactEmployee.setEmployeeId(empId);
                        contactEmployee.setStatus(1);
                        //endregion

                        Map<String, WorkContactTagPivotEntity> contactTagPivotMap = new HashMap<>();
                        JSONArray tags = followUserItem.getJSONArray("tags");
                        for (int l = 0; l < tags.size(); l++) {
                            JSONObject tag = tags.getJSONObject(l);
                            String tagId = tag.getString("tag_id");
                            if (tagId == null || tagId.isEmpty()) {
                                continue;
                            }
                            WorkContactTagPivotEntity contactTagPivot = new WorkContactTagPivotEntity();
                            contactTagPivot.setCreateTime(LocalDateTime.now());
                            contactTagPivot.setType(tag.getInteger("type"));
                            //contactTagPivot.setEmployeeId(empId);
                            // contactTagPivot.setContactId(contactId);
                            contactTagPivotMap.put(tag.getString("tag_id"), contactTagPivot);
                        }
                        employeeToTag.put(contactEmployee, contactTagPivotMap);
                        contactEmployeeMap.put(followUserItem.getString("userid"), employeeToTag);
                    }
                    contactBelongEmployee.put(contact, contactEmployeeMap);
                }
            }
            //endregion
            //region 上传头像到阿里云
            if (cotactAvatarPathMap.size() > 0 && wxAvatarUploadConfig.getEnabled()) {
                externalContactService.uploadContactAvatar(cotactAvatarPathMap);
            }
            //endregion
            return contactBelongEmployee;
        }
        return null;
    }

    /**
     * @description 获取流失客户
     * @author zhaojinjian
     * @createTime 2020/12/12 11:46
     */
    @Override
    public Page<List<ContactLossVO>> getlossContact(Integer corpId, List<Integer> empIds, Page page) {
        //获取员工下所有流失的客户Id map<empId,contactId>
        LossContact lossContact = workContactEmployeeService.getEmployeeLossContactId(corpId, empIds, (int)page.getCurrent(), (int)page.getSize());

        List<Integer> contactIds = new ArrayList<>(lossContact.getEmpIdAndContactId().values());

        List<WorkContactEntity> contactList = new ArrayList<>();
        if (!contactIds.isEmpty()) {
            //根据流失客户id获取客户详情集合
            QueryWrapper<WorkContactEntity> contactWrapper = new QueryWrapper<>();
            contactWrapper.in("id", contactIds);
            //获取流失客户信息
            contactList.addAll(this.list(contactWrapper));
        }

        //获取所有成员针对于客户的标签
        List<GetEmployeeTagModel> workContactTagList = contactTagService.getEmployeeTapName(empIds);

        //获取多个客户的归属成员
        Map<Integer, String> corpEmployeeName = workEmployeeService.getCorpEmployeeName(corpId, empIds);

        List<ContactLossVO> lossVOS = new LinkedList<>();
        for (Map.Entry<String, Integer> entry : lossContact.getEmpIdAndContactId().entrySet()) {
            Optional<WorkContactEntity> contactOp = contactList.stream().filter(c -> c.getId() == entry.getValue()).findAny();
            WorkContactEntity contactEntity = contactOp.get();
            Integer empId = Integer.parseInt(entry.getKey().split("-")[0]);
            ContactLossVO lossVO = new ContactLossVO();
            lossVO.setContactId(entry.getValue());
            lossVO.setAvatar(contactEntity.getAvatar());
            lossVO.setNickName(contactEntity.getNickName());
            lossVO.setDelFlag(contactEntity.getDelFlag());
            lossVO.setTag(workContactTagList.stream().filter(w -> w.getContactId() == contactEntity.getId() && w.getEmpId() == empId).map(GetEmployeeTagModel::getTagName).collect(toList()));
            lossVO.setEmployeeName(corpEmployeeName.get(empId));
            lossVOS.add(lossVO);
        }
        SubPage subPage = new SubPage();
        subPage.setRecords(lossVOS);
        subPage.setCurrent(lossContact.getPerPage());
        subPage.setSize(lossContact.getTotalPage());
        subPage.setTotal(lossContact.getTotal());
        return subPage;
    }

    /**
     * @description 回调函数--添加企业客户事件
     * @author zhaojinjian
     * @createTime 2020/12/16 19:05
     */
    @Override
    public void addExternalContact(String wxCorpId, String externalUserid, String userId, String welcomeCode, String state) {
        log.info("usesrId:"+userId);
        log.info("externalUserId:"+externalUserid);
        log.info("state:"+state);
        log.info("welcomeCode"+welcomeCode);
        WorkEmployeeEntity employeeEntity = workEmployeeService.getWorkEmployeeInfo(userId);
        Map<String,Object> contentMap = null;
        if (employeeEntity != null) {
            Integer empId = employeeEntity.getId();
            JSONArray contactUserid = new JSONArray();
            contactUserid.add(externalUserid);
            //获取微信客户详情
            Map<String, JSONObject> contactInfo = externalContactService.getExternalContactMap(contactUserid, employeeEntity.getCorpId());
           log.info("contactInfo="+contactInfo);
            Map<WorkContactEntity, Map<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>>> modelMap = externalContactToWorkContact(contactInfo, employeeEntity.getCorpId(), userId);
             log.info("modelMap="+modelMap);
            List<WorkContactEntity> contactList = modelMap.keySet().stream().collect(toList());
            log.info("contactList="+contactList);

            // 判断此客户是否已被其他成员添加
            WorkContactEntity contactEntity = getContactByCorpIdAndExternalUserid(CorpContextHolder.getCorpId(), externalUserid);
            // true-存在 false-不存在
            boolean exists = contactEntity == null ? false : true;
            // 客户是否添加成功
            boolean result = insertAllContact(contactList, employeeEntity.getCorpId());
            log.info("exists:{}-result:{}",exists, result);
            contactEntity = getOne(Wrappers.<WorkContactEntity>lambdaQuery().eq(WorkContactEntity::getCorpId,CorpContextHolder.getCorpId()).eq(WorkContactEntity::getWxExternalUserid,externalUserid));
            // 发放红包处理流程
            if (!exists && result) {
                //wxRedpackHandleService.handleRedpackOfCustTask(employeeEntity, contactEntity);
            }

            Integer lossId = contactLossService.getObj(Wrappers.<ContactLossEntity>lambdaQuery()
                    .select(ContactLossEntity::getId)
                    .eq(ContactLossEntity::getContactId, contactEntity.getId())
                    .eq(ContactLossEntity::getEmployeeId, employeeEntity.getId()), o -> Integer.parseInt(o.toString()));
            if (lossId != null) contactLossService.removeById(lossId);

            List<WorkContactTagPivotEntity> roomTags = new ArrayList<>();
            //获取客户Tag集合
            if (state != null && state.contains("workRoomAutoPullId")) {
                workRoomAutoPullIdHandle(state, welcomeCode, employeeEntity, contactEntity);
            }

            if (state != null && state.contains("channelCode")) {
                channelCodePreHandle(state, externalUserid, welcomeCode, wxCorpId, contactInfo, employeeEntity);
            } else if(state==null || state.contains("UQC")){
                contentMap = greetingServiceImpl.getGreeting(userId);
            }
            //发送欢迎语
//            if(state == null || state.equals("")){
            //sendWelcomeMsgService.send(employeeEntity.getCorpId(), welcomeCode, map);

//            }
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            log.info("contentMap为:"+contentMap);
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            if (contentMap != null && contentMap.get("content") != null){
                greetingServiceImpl.applyWxSendContactMessage(wxCorpId,welcomeCode,contactInfo,(Map<String,Object>)contentMap.get("content"));
            }

            if (result) {
                List<WorkContactEmployeeEntity> contactEmployeeList = new ArrayList<>();
                List<WorkContactTagPivotEntity> contactTagPivotList = new ArrayList<>();
                for (Map.Entry<WorkContactEntity, Map<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>>> entry : modelMap.entrySet()) {
                    for (Map.Entry<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>> aa : entry.getValue().entrySet()) {
                        for (Map.Entry<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>> bb : aa.getValue().entrySet()) {
                            bb.getKey().setContactId(entry.getKey().getId());
                            bb.getKey().setEmployeeId(empId);
                            List<String> wxTagIds = bb.getValue().keySet().stream().collect(toList());
                            Map<String, Integer> tagIds = contactTagService.getContactTagId(wxTagIds);
                            for (Map.Entry<String, WorkContactTagPivotEntity> cc : bb.getValue().entrySet()) {
                                cc.getValue().setContactId(entry.getKey().getId());
                                cc.getValue().setEmployeeId(empId);
                                cc.getValue().setContactTagId(tagIds.get(cc.getKey()));
                            }
                            contactTagPivotList.addAll(bb.getValue().values().stream().filter(c -> c.getContactTagId() != null).collect(toList()));
                        }
                        contactEmployeeList.addAll(aa.getValue().keySet().stream().collect(toList()));
                    }
                }
                if ((contactTagPivotList != null && contactTagPivotList.size() > 0) || roomTags.size() > 0) {
                    if (contactTagPivotList != null && contactTagPivotList.size() > 0) {
                        roomTags.addAll(contactTagPivotList);
                        if (roomTags.size() > 0) {
                            List<WorkContactTagPivotEntity> diffContactTagPivot = roomTags.stream().filter(item -> !contactTagPivotList.stream().map(e -> e.getId()).collect(toList()).contains(item.getId())).collect(toList());
                            //求出自动拉群和当前客户标签的差集
                            List<Integer> tagIdList = diffContactTagPivot.stream().map(WorkContactTagPivotEntity::getContactTagId).collect(toList());
                            if (tagIdList != null && tagIdList.size() > 0) {
                                //修改客户标签
                                corpTagService.wxUpdateTag(userId, externalUserid, tagIdList);
                            }
                        }
                    }
                    //                 result = contactTagPivotService.insertAllTagPivot(roomTags);
                }
                if (contactEmployeeList != null && contactEmployeeList.size() > 0) {
                    if(StrUtil.isNotEmpty(state) && state.startsWith(Constant.UQC_PREFIX)) {
                        CorpEntity corp = corpService.getCorpByWxCorpId(wxCorpId);
                        if (corp != null) {
                            Integer corpId = corp.getCorpId();
                            String[] ids = state.replace(Constant.UQC_PREFIX,"").split("-");
                            //获取邀请客户主键id
                            Integer contactId = Integer.valueOf(ids[0]);
                            //获取企业成员主键id
                            Integer employeeId = Integer.valueOf(ids[1]);
                            //获取受邀请客户主键id
                            Integer joinContactId = contactService.getContactId(externalUserid, corpId);
                            saveTrack(employeeId, contactId, joinContactId);
                            contactEmployeeList.removeIf(s -> (employeeId.equals(s.getEmployeeId()) && joinContactId.equals(s.getContactId())));
                        }
                    }
                    result = workContactEmployeeService.insertAllContactEmployee(contactEmployeeList,2);
                }
                // 添加互动轨迹
            }
        } else {
            //TODO  根据微信成员userid，没有在本地库找到对应的员工信息；
        }
        if (employeeEntity != null){
            if (state != null && state.contains("channelCode")) {
                Integer channelCodeId = Integer.parseInt(state.split("-")[1]);
                log.info("添加客户备注和描述");
                channelCodeService.updateRemarkAndDescription(employeeEntity.getCorpId(),channelCodeId,externalUserid,employeeEntity.getId());
                log.info("添加客户备注和描述成功");
                channelCodeContactStatisticsService.saveContact(employeeEntity.getCorpId());
                log.info("修改渠道活码信息");
                channelCodeService.updateChannelCodeQr(channelCodeId,employeeEntity.getCorpId());
                log.info("同步渠道活码信息成功");
            }
        }


    }


    private MediumEnyity getMedium(String mediumId) {
        return mediumService.getMediumById(Integer.valueOf(mediumId));
    }

    @Override
    public ContactDetailVO getContactDetailByWxExternalUserId(String wxExternalUserid) {
        WorkContactEntity workContactEntity = new WorkContactEntity();
        workContactEntity.setWxExternalUserid(wxExternalUserid);
        workContactEntity.setCorpId(CorpContextHolder.getCorpId());
        List<WorkContactEntity> contactEntityList = list(new QueryWrapper(workContactEntity));
        if (contactEntityList.size() < 1) {
            throw new CheckedException("未找到客户信息");
        }
        workContactEntity = contactEntityList.get(0);
        ContactDetailVO vo = new ContactDetailVO();
        vo.setId(workContactEntity.getId());
        vo.setName(workContactEntity.getName());
        vo.setAvatar(workContactEntity.getAvatar());
        vo.setCorpId(workContactEntity.getCorpId());
        return vo;
    }

    @Override
    public Page<List<ContactTrackVO>> getContactTrackByContactId(Integer contactId, Page page,Integer employeeId) {
        Integer corpId = CorpContextHolder.getCorpId();
        ContactEmployeeTrackEntity contactEmployeeTrackEntity = new ContactEmployeeTrackEntity();
        contactEmployeeTrackEntity.setContactId(contactId);
        contactEmployeeTrackEntity.setEmployeeId(employeeId);
        contactEmployeeTrackEntity.setCorpId(corpId);
        page = (Page) contactEmployeeTrackMapper
                .selectPage(page, new QueryWrapper<>(contactEmployeeTrackEntity).orderByDesc("create_time"));
        List<ContactEmployeeTrackEntity> records = page.getRecords();
        List<ContactTrackVO> listVo = new ArrayList<>();
        for (ContactEmployeeTrackEntity entity : records) {
            ContactTrackVO vo = new ContactTrackVO();
            vo.setId(entity.getId());
            vo.setEvent(entity.getEvent());
            vo.setContent(entity.getContent());
            vo.setCreateTime(DateUtils.asString(entity.getCreateTime()));
            listVo.add(vo);
        }
        SubPage subPage = new SubPage();
        subPage.setPages(page.getPages());
        subPage.setCurrent(page.getCurrent());
        subPage.setRecords(listVo);
        subPage.setSize(page.getSize());
        subPage.setTotal(page.getTotal());
        return subPage;
    }

    @Override
    public Page<List<ContactTrackVO>> getContactTrackByContactIdWechat(String wxUserId,String wxExternalUserid,Page page) {
        Integer corpId = CorpContextHolder.getCorpId();
        LocalDateTime now = LocalDateTime.now();
        WorkContactEntity contactEntity = workContactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery().eq(WorkContactEntity::getCorpId,corpId).eq(WorkContactEntity::getWxExternalUserid, wxExternalUserid).eq(BaseEntity::getDelFlag,0));
        WorkEmployeeEntity employeeEntity = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery().eq(WorkEmployeeEntity::getCorpId,corpId).eq(WorkEmployeeEntity::getWxUserId, wxUserId).eq(BaseEntity::getDelFlag, 0));
        QueryWrapper<ContactEmployeeTrackEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("channel",2).eq("corp_id",corpId).eq("employee_id",employeeEntity.getId()).eq("contact_id",contactEntity.getId()).orderByDesc("create_time");
        IPage page1 = contactEmployeeTrackMapper.selectPage(page, wrapper);
        if(page1==null){
            return page;
        }
        List<ContactEmployeeTrackEntity> records = page1.getRecords();
        List<ContactTrackVO> listVo = new ArrayList<>();
        for (ContactEmployeeTrackEntity entity : records) {
            ContactTrackVO vo = new ContactTrackVO();
            vo.setId(entity.getId());
            vo.setContent(entity.getContent());
            vo.setEvent(entity.getEvent());
            vo.setEventName(EventEnum.getByCode(entity.getEvent()));
            vo.setCreateTime(DateUtils.asString(entity.getCreateTime()));
            LocalDateTime createTime = entity.getCreateTime();
            Duration duration = Duration.between(createTime, now);
            if (duration.toMinutes() < 15) {
                vo.setState(2);
            } else {
                vo.setState(1);
            }
            listVo.add(vo);
        }
        SubPage subPage = new SubPage();
        subPage.setPages(page.getPages());
        subPage.setCurrent(page.getCurrent());
        subPage.setRecords(listVo);
        subPage.setSize(page.getSize());
        subPage.setTotal(page.getTotal());
        return subPage;
    }

    @Override
    public R getContactTrackListByContactIdWechat(String wxUserId, String wxExternalUserid, Integer type, Page page) {
        Integer corpId = CorpContextHolder.getCorpId();
        //转换分页数据为int
        Long current = (long) page.getCurrent();
        int i = current.intValue();
        //转换分页数据为int
        Long size =(long) page.getSize();
        int i1 = size.intValue();
        //通过wxUserId和wxExternalUserid获取各自的基本信息
        WorkContactEntity contactEntity = workContactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery().eq(WorkContactEntity::getCorpId,corpId).eq(WorkContactEntity::getWxExternalUserid, wxExternalUserid).eq(BaseEntity::getDelFlag,0));
        WorkEmployeeEntity employeeEntity = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery().eq(WorkEmployeeEntity::getCorpId,corpId).eq(WorkEmployeeEntity::getWxUserId, wxUserId).eq(BaseEntity::getDelFlag, 0));
         //设置获取动态的条件
        QueryWrapper<ContactEmployeeTrackEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("corp_id",corpId).eq("employee_id",employeeEntity.getId()).eq("contact_id",contactEntity.getId()).orderByDesc("create_time");
       //如果type=null 则查询客户动态和待办事项和跟进记录的用户对应客户的所有记录。
        if(null==type){
            //建立一个list存放前端展示对象。
            ArrayList<ContactTrackVO> contactTrackVOS = new ArrayList<>();
            //获取客户动态的记录
           contactEmployeeTrackMapper.selectList(wrapper).forEach(contactEmployeeTrackEntity -> {
               ContactTrackVO contactTrackVO = new ContactTrackVO();
               contactTrackVO.setContent(contactEmployeeTrackEntity.getContent());
               contactTrackVO.setCreateTime(DateUtils.asString(contactEmployeeTrackEntity.getCreateTime()));
               contactTrackVO.setEvent(contactEmployeeTrackEntity.getEvent());
               contactTrackVO.setEventName(EventEnum.getByCode(contactEmployeeTrackEntity.getEvent()));
               contactTrackVOS.add(contactTrackVO);
           });
           //获取待办的记录
            List<EmployeeDoEntity> list = employeeDoService.list(Wrappers.<EmployeeDoEntity>lambdaQuery().eq(EmployeeDoEntity::getWxExternalUserid, wxExternalUserid).eq(EmployeeDoEntity::getWxUserId, wxUserId).eq(BaseEntity::getDelFlag, 0).orderByDesc(BaseEntity::getCreateTime));
            list.forEach(employeeDoEntity -> {
                Instant instant = employeeDoEntity.getStartTime().toInstant();
                ZoneId zoneId = ZoneId.systemDefault();
                LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
                ContactTrackVO contactTrackVO = new ContactTrackVO();
                contactTrackVO.setContent(employeeDoEntity.getDoBody());
                contactTrackVO.setName(employeeEntity.getName());
                contactTrackVO.setEvent(25);
                contactTrackVO.setEventName(EventEnum.getByCode(25));
                contactTrackVO.setCreateTime(DateUtils.asString(employeeDoEntity.getCreateTime()));
                contactTrackVO.setStartTime(DateUtils.asString(localDateTime));
                contactTrackVOS.add(contactTrackVO);
            });
            //获取跟进的记录
            employeeFollowService.list(Wrappers.<EmployeeFollowEntity>lambdaQuery().eq(EmployeeFollowEntity::getWxExternalUserid, wxExternalUserid).eq(EmployeeFollowEntity::getWxUserId, wxUserId).eq(BaseEntity::getDelFlag, 0).orderByDesc(BaseEntity::getCreateTime))
                    .forEach(employeeFollowEntity -> {
                ContactTrackVO contactTrackVO = new ContactTrackVO();
                contactTrackVO.setContent(employeeFollowEntity.getFollowBody());
                contactTrackVO.setName(employeeEntity.getName());
                contactTrackVO.setEventName(EventEnum.getByCode(26));
                contactTrackVO.setEvent(26);
                contactTrackVO.setCreateTime(DateUtils.asString(employeeFollowEntity.getCreateTime()));
                contactTrackVOS.add(contactTrackVO);
            });
            //分页
           return R.ok(PageUtil.split(contactTrackVOS, i, i1));
        }else {
            switch (type){
                case 1:
                    IPage page1 = contactEmployeeTrackMapper.selectPage(page, wrapper);
                    if(page1==null){
                        ArrayList<Object> objects = new ArrayList<>();
                        page1.setRecords(objects);
                    }
                    List<ContactEmployeeTrackEntity> records = page1.getRecords();
                    List<ContactTrackVO> listVo = new ArrayList<>();
                    for (ContactEmployeeTrackEntity entity : records) {
                        ContactTrackVO vo = new ContactTrackVO();
                        vo.setId(entity.getId());
                        vo.setContent(entity.getContent());
                        vo.setEvent(entity.getEvent());
                        vo.setEventName(EventEnum.getByCode(entity.getEvent()));
                        vo.setCreateTime(DateUtils.asString(entity.getCreateTime()));
                        listVo.add(vo);
                    }
                    SubPage subPage = new SubPage();
                    subPage.setPages(page.getPages());
                    subPage.setCurrent(page.getCurrent());
                    subPage.setRecords(listVo);
                    subPage.setSize(page.getSize());
                    subPage.setTotal(page.getTotal());
                    return R.ok(subPage);
                case 2:
                    ArrayList<ContactTrackVO> contactTrackVOS = new ArrayList<>();
                    List<EmployeeDoEntity> list = employeeDoService.list(Wrappers.<EmployeeDoEntity>lambdaQuery().eq(EmployeeDoEntity::getCorpId,corpId).eq(EmployeeDoEntity::getWxExternalUserid, wxExternalUserid).eq(EmployeeDoEntity::getWxUserId, wxUserId).eq(BaseEntity::getDelFlag, 0).orderByDesc(BaseEntity::getCreateTime));
                    list.forEach(employeeDoEntity -> {
                        Instant instant = employeeDoEntity.getStartTime().toInstant();
                        ZoneId zoneId = ZoneId.systemDefault();
                        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
                        ContactTrackVO contactTrackVO = new ContactTrackVO();
                        contactTrackVO.setContent(employeeDoEntity.getDoBody());
                        contactTrackVO.setName(employeeEntity.getName());
                        contactTrackVO.setCreateTime(DateUtils.asString(employeeDoEntity.getCreateTime()));
                        contactTrackVO.setStartTime(DateUtils.asString(localDateTime));
                        contactTrackVO.setEventName(EventEnum.getByCode(25));
                        contactTrackVO.setEvent(25);
                        contactTrackVOS.add(contactTrackVO);
                    });
                    return R.ok(PageUtil.split(contactTrackVOS,i,i+1));
                case 3:
                    ArrayList<ContactTrackVO> contactTrackVOS1 = new ArrayList<>();
                    employeeFollowService.list(Wrappers.<EmployeeFollowEntity>lambdaQuery().eq(EmployeeFollowEntity::getCorpId,corpId).eq(EmployeeFollowEntity::getWxExternalUserid, wxExternalUserid).eq(EmployeeFollowEntity::getWxUserId, wxUserId).eq(BaseEntity::getDelFlag, 0).orderByDesc(BaseEntity::getCreateTime))
                            .forEach(employeeFollowEntity -> {
                                ContactTrackVO contactTrackVO = new ContactTrackVO();
                                contactTrackVO.setContent(employeeFollowEntity.getFollowBody());
                                contactTrackVO.setName(employeeEntity.getName());
                                contactTrackVO.setCreateTime(DateUtils.asString(employeeFollowEntity.getCreateTime()));
                                contactTrackVO.setEventName(EventEnum.getByCode(26));
                                contactTrackVO.setEvent(26);
                                contactTrackVOS1.add(contactTrackVO);
                            });
                    return R.ok(PageUtil.split(contactTrackVOS1,i,i+1));
                default:
                    break;
            }
        }
return null;
    }

    @Override
    public void saveTrack(Integer employeeId, Integer contactId, EventEnum eventEnum, String content, Integer channel, Integer corpId) {
        if (CorpContextHolder.getCorpId() != null) {
            corpId = CorpContextHolder.getCorpId();
        }
//        Integer corpId = CorpContextHolder.getCorpId();
        ContactEmployeeTrackEntity contactEmployeeTrackEntity = new ContactEmployeeTrackEntity();
        contactEmployeeTrackEntity.setEmployeeId(employeeId);
        contactEmployeeTrackEntity.setContactId(contactId);
        contactEmployeeTrackEntity.setEvent(eventEnum.getCode());
        contactEmployeeTrackEntity.setContent(content);
        contactEmployeeTrackEntity.setChannel(channel);
        contactEmployeeTrackEntity.setCorpId(corpId);
        contactEmployeeTrackEntity.setCreateTime(DateUtil.toLocalDateTime(DateTime.now()));
        contactEmployeeTrackMapper.insert(contactEmployeeTrackEntity);
    }

    @Override
    public void saveTrackProd(Integer corpId, Integer employeeId, Integer contactId, EventEnum eventEnum, String content, Integer channel) {
        ContactEmployeeTrackEntity contactEmployeeTrackEntity = new ContactEmployeeTrackEntity();
        contactEmployeeTrackEntity.setEmployeeId(employeeId);
        contactEmployeeTrackEntity.setContactId(contactId);
        contactEmployeeTrackEntity.setEvent(eventEnum.getCode());
        contactEmployeeTrackEntity.setContent(content);
        contactEmployeeTrackEntity.setChannel(channel);
        contactEmployeeTrackEntity.setCorpId(corpId);
        contactEmployeeTrackEntity.setCreateTime(DateUtil.toLocalDateTime(DateTime.now()));
        contactEmployeeTrackMapper.insert(contactEmployeeTrackEntity);
    }


    @Override
    public R<Page<ContactClientListVO>> getClientList(String wxUserId, Integer roomId, Page page) {
        WorkEmployeeEntity employeeEntity = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getWxUserId, wxUserId)
                .eq(WorkEmployeeEntity::getCorpId,CorpContextHolder.getCorpId()));
        List<WorkContactEmployeeEntity> workContactEmployeeEntities = workContactEmployeeService.list(Wrappers.<WorkContactEmployeeEntity>lambdaQuery()
                .eq(WorkContactEmployeeEntity::getEmployeeId, employeeEntity.getId())
                .eq(WorkContactEmployeeEntity::getCorpId,CorpContextHolder.getCorpId()));
        if (workContactEmployeeEntities.isEmpty()){
            return R.ok(new SubPage());
        }
        List<Integer> contactIds = new LinkedList<>();
        List<ContactClientListVO> vos = new LinkedList<>();
        for (WorkContactEmployeeEntity w : workContactEmployeeEntities) {
            ContactClientListVO vo = new ContactClientListVO();
            contactIds.add(w.getContactId());
            BeanUtil.copyProperties(w,vo);
            vo.setAddWayText(AddWayEnum.getByCode(vo.getAddWay()));
            vos.add(vo);
        }
        if (roomId != null) {
            List<Integer> roomContactIds = workContactRoomService.list(Wrappers.<WorkContactRoomEntity>lambdaQuery()
                    .eq(WorkContactRoomEntity::getRoomId, roomId))
                    .stream()
                    .map(WorkContactRoomEntity::getContactId)
                    .distinct()
                    .collect(toList());
            //对两个集合求交集，以获取当前客户群内此成员关联的外部联系人
            contactIds.retainAll(roomContactIds);
            vos = vos.stream().filter(v->contactIds.contains(v.getContactId())).collect(toList());
        }
        List<WorkContactEntity> list = list(Wrappers.<WorkContactEntity>lambdaQuery().in(WorkContactEntity::getId, contactIds));

        vos.forEach(v->{
            for (int i = 0; i < list.size(); i++) {
                if (v.getContactId().equals(list.get(i).getId())){
                    BeanUtil.copyProperties(list.get(i),v);
                    v.setTypeText(v.getType()==1 ? "微信": list.get(i).getCorpName());
                    DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    v.setAddTime(pattern.format(list.get(i).getCreateTime()));
                }
            }
        });
        Page<ContactClientListVO> voPage = PageUtil.split(vos, (int) page.getCurrent(), (int) page.getSize());
        return R.ok(voPage);
    }

    /**
     * 获取登录用户同一部门全部用户信息
     *
     * @param userId 登录用户id
     * @return List<WorkEmployeeDepartmentEntity>
     */
    public List<WorkEmployeeDepartmentEntity> getEmployeeList(Integer userId){
        WorkEmployeeDepartmentEntity entity = employeeDepartmentService.getOne(Wrappers.<WorkEmployeeDepartmentEntity>lambdaQuery()
                .eq(WorkEmployeeDepartmentEntity::getEmployeeId, userId));
        return employeeDepartmentService.list(Wrappers
                .<WorkEmployeeDepartmentEntity>lambdaQuery()
                .eq(WorkEmployeeDepartmentEntity::getDepartmentId,entity.getDepartmentId()));
    }

    @Override
    public IPage<ContactEmployeeTagVO> getContactListByUser(Page page,Integer employeeId) {
        Integer corpId = CorpContextHolder.getCorpId();
        RemindCommunicationEntity communicationEntity = remindCommunicationService.getOne(Wrappers.<RemindCommunicationEntity>lambdaQuery().eq(RemindCommunicationEntity::getCorpId, corpId).orderByDesc(BaseEntity::getCreateTime).last("limit 1"));
       //未交流客户配置
        if(null==communicationEntity){
            throw new CheckedException("未交流提醒已关闭");
        }
        List<Integer> tagIds = JSONUtil.toList(JSONUtil.parseArray(communicationEntity.getTagIds()),Integer.class);
        if (tagIds.isEmpty()) {
            return page;
        }
        if(ObjectUtil.isEmpty(employeeId)) {
            MadpUser user = SecurityUtils.getUser();
            log.info("user:"+user);
            Integer id = user.getId();
            log.info("id:"+id);
            List<WorkEmployeeEntity> employeeEntities = workEmployeeService.list(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .select(WorkEmployeeEntity::getId)
                    .eq(WorkEmployeeEntity::getLogUserId, id)
                    .eq(WorkEmployeeEntity::getCorpId, corpId));
            if(employeeEntities.size() == 0){
                return page;
            }
            //获取登录用户同一部门全部用户信息
            List<WorkEmployeeDepartmentEntity> list = getEmployeeList(employeeEntities.get(0).getId());
            if (list.size()==0){
                return page;
            }
            ArrayList<ContactEmployeeTagVO> contactEmployeeTagVOS = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                //该部门下任意用户
                WorkEmployeeDepartmentEntity workEmployeeDepartmentEntity = list.get(i);
                WorkEmployeeEntity employeeEntity = employeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery().eq(WorkEmployeeEntity::getId, workEmployeeDepartmentEntity.getEmployeeId()));
               if(employeeEntity==null){
                   continue;
               }
               //该用户名下符合条件的客户
                List<ContactByTagDto> contactByTagDtoList = baseMapper.getContactByEmployee(corpId, tagIds, employeeEntity.getName());
                for (ContactByTagDto contact:contactByTagDtoList){
                    //聊天记录
                    WorkMsgEntity workMsgEntity = workMsgMapper.countTime(contact.getWxUserId(),contact.getWxExternalUserid(),corpId);
                    if(null==workMsgEntity){
                        continue;
                    }
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date nowTime =DateUtils.asDate(LocalDateTime.now());
                    Date endTime = DateUtils.asDate(DateUtils.asLocalDateTime(sdf.format(new Date(Long.parseLong(workMsgEntity.getMsgTime())))));
                    //未交流天数
                    long between = DateUtil.between(endTime, nowTime, DateUnit.DAY);
                    if(between>communicationEntity.getTime()){
                        ContactEmployeeTagVO contactEmployeeTagVO= new ContactEmployeeTagVO();
                        contactEmployeeTagVO.setContactId(contact.getContactId());
                        contactEmployeeTagVO.setContactName(contact.getContactName());
                        contactEmployeeTagVO.setEmployeeId(contact.getEmployeeId());
                        contactEmployeeTagVO.setWxUserId(contact.getWxUserId());
                        contactEmployeeTagVO.setEmployeeName(contact.getEmployeeName());
                        contactEmployeeTagVO.setCreateTime(contact.getCreateTime());
                        contactEmployeeTagVO.setDay(String.valueOf(between));
                        contactEmployeeTagVO.setEndTime(DateUtils.asString(DateUtils.asLocalDateTime(sdf.format(new Date(Long.parseLong(workMsgEntity.getMsgTime()))))));
                        List<Map> tagByContact = baseMapper.getTagByContact(contact.getContactId(), contact.getEmployeeId(), corpId);
                        List<ContactEmployeeTagVO.tagListVO> tagListVOS = tagByContact.stream().map(map -> {
                            int tagId = Integer.parseInt(map.get("tagId").toString());
                            String tagName = map.get("tagName").toString();
                            ContactEmployeeTagVO.tagListVO tagListVO = new ContactEmployeeTagVO.tagListVO();
                            tagListVO.setTagName(tagName);
                            tagListVO.setTagId(tagId);
                            return tagListVO;
                        }).collect(toList());
                        contactEmployeeTagVO.setTagList(tagListVOS);
                        contactEmployeeTagVOS.add(contactEmployeeTagVO);
                    }
                  }
               }
            List<ContactEmployeeTagVO> collect = contactEmployeeTagVOS.stream().distinct().sorted(Comparator.comparing(ContactEmployeeTagVO::getEndTime).reversed()).filter(map->map.getTagList().size()>0).collect(toList());
            return PageUtil.split(collect, (int) page.getCurrent(), (int) page.getSize());
        }else {
            ArrayList<ContactEmployeeTagVO> contactEmployeeTagVOS = new ArrayList<>();
            //该用户名下符合条件的客户
            WorkEmployeeEntity workEmployeeServiceOne = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .select(WorkEmployeeEntity::getName)
                    .eq(WorkEmployeeEntity::getId, employeeId)
                    .eq(WorkEmployeeEntity::getCorpId, corpId));
            List<ContactByTagDto> contactByTagDtoList = baseMapper.getContactByEmployee(corpId, tagIds, workEmployeeServiceOne.getName());
            if(contactByTagDtoList.size()==0){
                return page;
            }
            for (ContactByTagDto contact : contactByTagDtoList) {
                //聊天记录
                WorkMsgEntity workMsgEntity = workMsgMapper.countTime(contact.getWxUserId(), contact.getWxExternalUserid(), corpId);
                if (null == workMsgEntity) {
                    continue;
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date nowTime = DateUtils.asDate(LocalDateTime.now());
                Date endTime = DateUtils.asDate(DateUtils.asLocalDateTime(sdf.format(new Date(Long.parseLong(workMsgEntity.getMsgTime())))));
                //未交流天数
                long between = DateUtil.between(endTime, nowTime, DateUnit.DAY);
                if (between > communicationEntity.getTime()) {
                    ContactEmployeeTagVO contactEmployeeTagVO = new ContactEmployeeTagVO();
                    contactEmployeeTagVO.setContactId(contact.getContactId());
                    contactEmployeeTagVO.setContactName(contact.getContactName());
                    contactEmployeeTagVO.setEmployeeId(contact.getEmployeeId());
                    contactEmployeeTagVO.setWxUserId(contact.getWxUserId());
                    contactEmployeeTagVO.setEmployeeName(contact.getEmployeeName());
                    contactEmployeeTagVO.setCreateTime(contact.getCreateTime());
                    contactEmployeeTagVO.setDay(String.valueOf(between));
                    contactEmployeeTagVO.setEndTime(DateUtils.asString(DateUtils.asLocalDateTime(sdf.format(new Date(Long.parseLong(workMsgEntity.getMsgTime()))))));
                    List<Map> tagByContact = baseMapper.getTagByContact(contact.getContactId(), contact.getEmployeeId(), corpId);
                    List<ContactEmployeeTagVO.tagListVO> tagListVOS = tagByContact.stream().map(map -> {
                        int tagId = Integer.parseInt(map.get("tagId").toString());
                        String tagName = map.get("tagName").toString();
                        ContactEmployeeTagVO.tagListVO tagListVO = new ContactEmployeeTagVO.tagListVO();
                        tagListVO.setTagName(tagName);
                        tagListVO.setTagId(tagId);
                        return tagListVO;
                    }).collect(toList());
                    contactEmployeeTagVO.setTagList(tagListVOS);
                    contactEmployeeTagVOS.add(contactEmployeeTagVO);
                }
            }
            List<ContactEmployeeTagVO> collect = contactEmployeeTagVOS.stream().distinct().sorted(Comparator.comparing(ContactEmployeeTagVO::getEndTime).reversed()).filter(map->map.getTagList().size()>0).collect(toList());
            return PageUtil.split(collect, (int) page.getCurrent(), (int) page.getSize());
        }
    }
    @Override
    public void getGZHMsgToUserByLink(WxGZHDto dto) {
        Integer corpId = CorpContextHolder.getCorpId();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser",dto.getWxEmployeeId());
        jsonObject.put("msgtype","news");
        jsonObject.put("agentid", Constant.SEND_MSG_AGENT_ID2);


        HashMap<String, String> map = new HashMap<>();
        map.put("title", "回答客户问题");
        map.put("url", "/gzh/response" + "/openid=" + dto.getOpenId() + "/unionid=" + dto.getUnionId());
        JSONObject news = new JSONObject();
        JSONArray array = new JSONArray();
        news.put("articles", array);
        array.add(map);
        jsonObject.put("news",news);
        String s = jsonObject.toString();
        String wxCorpId = corpService.getById(corpId).getWxCorpId();
        WxApiUtils.sendMsgToEmployeeByLink(s,corpId, wxCorpId);
    }
    @Override
    public void getMsgToUser(MsgToEmployeeDTO dto) {
        //获取发送应用id
        Integer corpId = CorpContextHolder.getCorpId();
        String wxCorpId = corpService.getById(corpId).getWxCorpId();
        String text = dto.getText().get("content").toString().replaceAll(dto.getText().get("content").toString(),"客户："+dto.getContactName()+"，"+dto.getText().get("content").toString());
        dto.getText().put("content", text);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser",dto.getUserId());
        jsonObject.put("msgtype","text");
        jsonObject.put("agentid", corpService.getWxSendMsgAgentIdByWxCorpId(wxCorpId));
        jsonObject.put("text",dto.getText());
        String s = jsonObject.toString();
        WxApiUtils.sendMsgToEmployeeByString(s,corpId,wxCorpId);
    }

    @Override
    public void getUserToContact(MsgToEmployeeDTO dto) {
        Integer corpId = CorpContextHolder.getCorpId();
        //获取发送应用id
        String wxCorpId = corpService.getById(corpId).getWxCorpId();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser",dto.getUserId());
        jsonObject.put("msgtype","text");
        jsonObject.put("agentid", corpService.getWxSendMsgAgentIdByWxCorpId(wxCorpId));
        jsonObject.put("text",dto.getText());
        String s = jsonObject.toString();
        WxApiUtils.sendMsgToEmployeeByString(s,corpId,wxCorpId);
    }

    @Override
    public IPage<List<IndexMsgBO>>  getUserMsg(Integer contactId, Integer employeeId,Integer time,Integer type, Page page) {
        Integer corpId = CorpContextHolder.getCorpId();
        WorkContactEntity tempResultContact = getOne(Wrappers.<WorkContactEntity>lambdaQuery().eq(WorkContactEntity::getId,contactId).eq(WorkContactEntity::getCorpId,corpId));
        WorkEmployeeEntity tempResultEmployee = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery().eq(WorkEmployeeEntity::getId,employeeId).eq(WorkEmployeeEntity::getCorpId,corpId));
        String fromWxId = tempResultEmployee.getWxUserId();
        String fromName = tempResultEmployee.getName();
        String fromAvatar = tempResultEmployee.getAvatar();
        Map<String, Object> selectParamMap = new HashMap<>(9);
        selectParamMap.put("corpId", corpId);
        selectParamMap.put("from", tempResultEmployee.getWxUserId());
        selectParamMap.put("to", tempResultContact.getWxExternalUserid());
      //  selectParamMap.put("toUserType", 0);
        selectParamMap.put("dateTimeStart",String.valueOf(DateUtil.offsetDay(new Date(),-time-3).getTime()) );
        selectParamMap.put("dateTimeEnd", String.valueOf((DateUtil.offsetDay(new Date(),-time)).getTime()));
        selectParamMap.put("page", page.getCurrent());
        selectParamMap.put("size", page.getSize());
        selectParamMap.put("msgType",type);
        List<WorkMsgEntity> resultList = workMsgMapper.selectContactToUserMsg(selectParamMap);
        int total = workMsgMapper.selectContactToUserMsgCount(selectParamMap);
        List<IndexMsgBO> respList = new ArrayList<>();
        WorkEmployeeEntity tempEmployee = new WorkEmployeeEntity();
        WorkContactEntity tempContact = new WorkContactEntity();
        for (int i = 0; i < resultList.size(); i++) {
            WorkMsgEntity result = resultList.get(i);
            IndexMsgBO indexMsgBO = new IndexMsgBO();

            String resultFromWxId = result.getFrom();
            int isCurrentUser = fromWxId.equals(resultFromWxId) ? 1 : 0;
             indexMsgBO.setToListType(result.getTolistType());
            indexMsgBO.setIsCurrentUser(isCurrentUser);
            indexMsgBO.setAction(MsgEnum.getEnum(result.getAction()));

            int typeCode = result.getMsgType();
            typeCode = typeCode > 13 ? 100 : typeCode;

            indexMsgBO.setType(typeCode);
            indexMsgBO.setContent(JSON.parseObject(result.getContent()));

            String msgTime = result.getMsgTime();
            indexMsgBO.setMsgDataTime(DateUtils.formatS1(msgTime));

            String resultFromName;
            String resultFromAvatar;
            if (isCurrentUser == 1) {
                resultFromName = fromName;
                resultFromAvatar = fromAvatar;
            } else {
                if (WorkMsgBackUpUtil.isContact(resultFromWxId)) {
                    tempContact.setWxExternalUserid(resultFromWxId);
                    resultFromName = tempResultContact.getName();
                    resultFromAvatar = tempResultContact.getAvatar();
                } else {
                    tempEmployee.setWxUserId(resultFromWxId);
                    resultFromName = tempResultEmployee.getName();
                    resultFromAvatar = tempResultEmployee.getAvatar();
                }
            }

            indexMsgBO.setName(resultFromName);
            indexMsgBO.setAvatar(resultFromAvatar);

            respList.add(indexMsgBO);
        }
        int size = (int) page.getSize();
        int pages = total/size;
        if (total%size > 0) {
            pages ++;
        }
        page.setRecords(respList);
        page.setTotal(total);
        page.setPages(pages);
        return page;
    }

    @Override
    public Map<String,Integer> getUserCount(String wxUserId) {
        Integer corpId = CorpContextHolder.getCorpId();
        Map<String, Object> selectParamMap = new HashMap<>(9);
        selectParamMap.put("corpId",corpId);
        selectParamMap.put("from", wxUserId);
        selectParamMap.put("toListType", 1);
        RemindCommunicationEntity communicationEntity = remindCommunicationService.getOne(Wrappers.<RemindCommunicationEntity>lambdaQuery()
                .eq(RemindCommunicationEntity::getCorpId, corpId)
                .orderByDesc(BaseEntity::getCreateTime)
                .last("limit 1"));
        if(null==communicationEntity){
            throw new CheckedException("未交流提醒已关闭");
        }
        selectParamMap.put("dateTimeEnd",String.valueOf(DateUtil.offsetDay(new Date(),-communicationEntity.getTime()).getTime()));
        List<String> contactWXUserId = workMsgMapper.getContactWXUserId(selectParamMap);
        Integer count = 0;
        List<String> strings = Arrays.asList(StrUtil.strip(communicationEntity.getTagIds(),"[","]").replace("\n","").replaceAll(" ","").split(","));
        for (int i = 0; i < contactWXUserId.size(); i++) {
            List<String> contactTags = workMsgMapper.getContactTags(StrUtil.strip(contactWXUserId.get(i), "[\"","\"]"));
            if(contactTags.size()>0) {
                List<String> intersection = strings.stream().filter(item -> contactTags.contains(item)).collect(toList());
                if(!intersection.isEmpty()){
                    count++;
                }
            }
        }
        if (count==0){
            communicationEntity.setTime(0);
        }
        HashMap<String, Integer> hashMap = new HashMap<>();
        hashMap.put("count",count);
        hashMap.put("time",communicationEntity.getTime());
        return hashMap;
    }

    /**
     * 获取客户信息列表
     * @param page
     * @param dto
     * @return
     */
    @Override
    public Page<ContactPageVO> getPageList(Page page, ContactPageDTO dto) {
        String syncContactTime = updateTimeService.getLastUpdateTime(TypeEnum.CONTACT);
        SubPage subPage = new SubPage();
        subPage.getExtraProps().put("syncContactTime",syncContactTime);

        //当前登录用户所在机构以及所有子级机构下的成员idList
        Set<Integer> employees = getEmployees(SecurityUtils.getUser().getDeptId());
        if (employees.isEmpty()) {
            return subPage;
        }

        List<Integer> contactId = workContactEmployeeService.list(Wrappers.<WorkContactEmployeeEntity>lambdaQuery()
                .eq(WorkContactEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                .in(WorkContactEmployeeEntity::getEmployeeId,employees))
                .stream().map(WorkContactEmployeeEntity::getContactId).collect(toList())
                .stream().distinct().collect(toList());
        if (contactId.isEmpty()) {
            return subPage;
        }

        //CRM客户姓名查询
        if (!StrUtil.isBlank(dto.getCrmName())) {
            CrmCustomQueryConditionDTO queryCondition = new CrmCustomQueryConditionDTO();
            queryCondition.setPecustName(dto.getCrmName());
            List<String> crmMobiles = workCustomInfoService.listByCondition(queryCondition)
                    .stream()
                    .map(WorkCustomInfoEntity::getMobileTel)
                    .collect(Collectors.toList());
            if (crmMobiles.isEmpty()) {
                return subPage;
            }
            List<WorkContactEmployeeEntity> contactEmployeeEntityList = workContactEmployeeService.list();
            contactEmployeeEntityList.forEach(l->{
                l.setRemarkMobiles(JSONArray.parseArray(l.getRemarkMobiles()).isEmpty() ? "" : JSONArray.parseArray(l.getRemarkMobiles()).get(0).toString());
            });
            List<Integer> contactIds = contactEmployeeEntityList.stream()
                    .filter(l -> crmMobiles.contains(l.getRemarkMobiles()))
                    .map(WorkContactEmployeeEntity::getContactId)
                    .distinct()
                    .collect(Collectors.toList());
            if (contactIds.isEmpty()) {
                return subPage;
            }
            Collection<WorkContactEntity> resultList = workContactService.listByIds(contactIds);
            List<ContactPageVO> vos = new LinkedList<>();
            resultList.forEach(r->{
                handleContactPageVOData(r,vos);
            });
            Page<ContactPageVO> split = PageUtil.split(vos, (int) page.getCurrent(), (int) page.getSize());
            subPage.setRecords(split.getRecords());
            subPage.setSize(split.getSize());
            subPage.setTotal(split.getTotal());
            subPage.setCurrent(split.getCurrent());
            return subPage;
        }

        //手机号精确查询
        if (!StrUtil.isBlank(dto.getMobile())) {
            List<WorkContactEmployeeEntity> contactEmployeeEntityList = workContactEmployeeService.list(Wrappers.<WorkContactEmployeeEntity>lambdaQuery()
                    .eq(WorkContactEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                    .in(WorkContactEmployeeEntity::getEmployeeId, employees));
            contactEmployeeEntityList.forEach(l->{
                l.setRemarkMobiles(JSONArray.parseArray(l.getRemarkMobiles()).isEmpty() ? "" : JSONArray.parseArray(l.getRemarkMobiles()).get(0).toString());
            });

            List<Integer> contactIdList = contactEmployeeEntityList.stream()
                    .filter(l -> l.getRemarkMobiles().equals(dto.getMobile()))
                    .map(WorkContactEmployeeEntity::getContactId)
                    .distinct()
                    .collect(Collectors.toList());
            if (contactIdList.isEmpty()) {
                return subPage;
            }
            Collection<WorkContactEntity> resultList = this.listByIds(contactIdList);
            List<ContactPageVO> vos = new LinkedList<>();
            resultList.forEach(r->{
                handleContactPageVOData(r,vos);
            });
            Page<ContactPageVO> split = PageUtil.split(vos, (int) page.getCurrent(), (int) page.getSize());
            subPage.setRecords(split.getRecords());
            subPage.setSize(split.getSize());
            subPage.setTotal(split.getTotal());
            subPage.setCurrent(split.getCurrent());
            return subPage;
        }

        //客户号精确查询
        if (!StrUtil.isBlank(dto.getCustNo())) {
            CrmCustomQueryConditionDTO queryCondition = new CrmCustomQueryConditionDTO();
            queryCondition.setCustNo(dto.getCustNo());
            List<WorkCustomInfoEntity> workCustomInfoEntitys = workCustomInfoService.listByCondition(queryCondition);
            if (workCustomInfoEntitys.isEmpty()) {
                return subPage;
            }
            List<WorkContactEmployeeEntity> contactEmployeeEntityList = workContactEmployeeService.list(Wrappers.<WorkContactEmployeeEntity>lambdaQuery()
                    .eq(WorkContactEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                    .in(WorkContactEmployeeEntity::getEmployeeId, employees));
            contactEmployeeEntityList.forEach(l->{
                l.setRemarkMobiles(JSONArray.parseArray(l.getRemarkMobiles()).isEmpty() ? "" : JSONArray.parseArray(l.getRemarkMobiles()).get(0).toString());
            });
            List<Integer> contactIdList = contactEmployeeEntityList.stream()
                    .filter(l -> l.getRemarkMobiles().equals(workCustomInfoEntitys.get(0).getMobileTel()))
                    .map(WorkContactEmployeeEntity::getContactId)
                    .distinct()
                    .collect(Collectors.toList());
            log.info("contactIdList:{}",contactIdList);
            if (contactIdList.isEmpty()) {
                return subPage;
            }
            Collection<WorkContactEntity> resultList = this.listByIds(contactIdList);
            List<ContactPageVO> vos = new LinkedList<>();
            resultList.forEach(r->{
                handleContactPageVOData(r,vos);
            });
            List<ContactPageVO> collect = vos.stream().filter(v -> v.getBusinessNo().equals(dto.getCustNo())).collect(Collectors.toList());
            Page<ContactPageVO> split = PageUtil.split(collect, (int) page.getCurrent(), (int) page.getSize());
            subPage.setRecords(split.getRecords());
            subPage.setSize(split.getSize());
            subPage.setTotal(split.getTotal());
            subPage.setCurrent(split.getCurrent());
            return subPage;

        }
        QueryWrapper<WorkContactEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("corp_id",CorpContextHolder.getCorpId());
        wrapper.in("id",contactId);
        wrapper.orderByDesc("create_time");
        if (!StrUtil.isBlank(dto.getName())){
            wrapper.like("name",dto.getName());
        }
        if (dto.getGender() !=null){
            wrapper.eq("gender",dto.getGender());
        }
        if (dto.getType() != null){
            wrapper.eq("type",dto.getType());
        }
        IPage iPage = page(page, wrapper);
        List<WorkContactEntity> records = iPage.getRecords();
        List<ContactPageVO> vos = new LinkedList<>();
        records.forEach(r->{
            handleContactPageVOData(r,vos);
        });

        subPage.setRecords(vos);
        subPage.setSize(iPage.getSize());
        subPage.setTotal(iPage.getTotal());
        subPage.setCurrent(iPage.getCurrent());
        return subPage;
    }


    private void handleContactPageVOData(WorkContactEntity r, List<ContactPageVO> vos) {
        ContactPageVO vo = new ContactPageVO();
        BeanUtil.copyProperties(r,vo);
        vo.setTypeText(vo.getType() == 1 ? "微信用户" : "企业微信用户");
        if (vo.getGender() == 0) {
            vo.setGenderText("未知");
        } else {
            vo.setGenderText(vo.getGender() == 1 ? "男" : "女");
        }
        List<WorkContactEmployeeEntity> contactEmployeeList = workContactEmployeeService.list(new LambdaQueryWrapper<WorkContactEmployeeEntity>()
                .eq(WorkContactEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(WorkContactEmployeeEntity::getContactId, vo.getId()));
        //取最早添加为外部联系人的记录
        WorkContactEmployeeEntity min = contactEmployeeList.stream().min(Comparator.comparing(l -> l.getCreateTime())).get();
        vo.setMobile(JSONArray.parseArray(min.getRemarkMobiles()).isEmpty() ? "" : JSONArray.parseArray(min.getRemarkMobiles()).get(0).toString());
        if (!StrUtil.isBlank(vo.getMobile())) {
            //根据手机号关联CRM客户信息
            CrmCustomQueryConditionDTO queryCondition = new CrmCustomQueryConditionDTO();
            queryCondition.setMobileTel(vo.getMobile());
            List<WorkCustomInfoEntity> workCustomInfoEntities = workCustomInfoService.listByCondition(queryCondition);
            vo.setCrmName(workCustomInfoEntities.isEmpty() ? "" : workCustomInfoEntities.get(0).getPecustName());
            vo.setBusinessNo(workCustomInfoEntities.isEmpty() ? "" : workCustomInfoEntities.get(0).getCustNo());
        }
        vos.add(vo);
    }

    /**
     * 获取企业客户基础信息
     * @param id
     * @param custNo
     * @return
     */
    @Override
    public ContactNewDetailsVO getContactDetails(Integer id, String custNo) {
        //获取客户基本信息
        WorkContactEntity entity = getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(WorkContactEntity::getId, id));
        if (entity == null){
            throw new CheckedException("当前客户已与本企业解除合作关系");
        }
        ContactNewDetailsVO vo = new ContactNewDetailsVO();
        BeanUtil.copyProperties(entity,vo);
        //写入客户来源
        vo.setTypeText(vo.getType() == 1 ? "微信用户" : "企业微信用户");
        //写入客户性别
        if (vo.getGender() == 0) {
            vo.setGenderText("未知");
        } else {
            vo.setGenderText(vo.getGender() == 1 ? "男" : "女");
        }
        //获取客户所在客户群列表id
        List<Integer> roomIds = contactRoomService.list(Wrappers.<WorkContactRoomEntity>lambdaQuery()
                .eq(WorkContactRoomEntity::getContactId, id))
                .stream().map(WorkContactRoomEntity::getRoomId).collect(toList());

        List<String> roomNames = new LinkedList<>();

        //当客户有在客户群时，获取客户所在客户群列表
        if (!roomIds.isEmpty()){
            roomNames = roomService.list(Wrappers.<WorkRoomEntity>lambdaQuery()
                    .eq(WorkRoomEntity::getCorpId,CorpContextHolder.getCorpId())
                    .in(WorkRoomEntity::getId,roomIds))
                    .stream().map(WorkRoomEntity::getName).collect(toList());
        }
        vo.setRoomList(roomNames);

        //当关联CRM客户时，获取资产信息(资产信息表)
        if (!StrUtil.isBlank(custNo)) {
            CustomerAssetsInfoVO customerAssetsInfoVO = new CustomerAssetsInfoVO();
            List<WorkAssetsInfoEntity> workAssetsInfoEntities = workAssetsInfoService.listByCustNo(custNo);
            if (!workAssetsInfoEntities.isEmpty()) {
                BeanUtil.copyProperties(workAssetsInfoEntities.get(0),customerAssetsInfoVO);
            }
            vo.setCustomerAssetsInfoVO(customerAssetsInfoVO);
        }

        return vo;
    }

    /**
     * 根据客户id获取员工与客户信息列表
     * @param page
     * @param id
     * @return
     */
    @Override
    public Page<EmployeeListByContactVO> getEmployeeListByContact(Page page, Integer id) {
        //分页查询员工与客户对应列表
         page = (Page) workContactEmployeeService.page(page, Wrappers.<WorkContactEmployeeEntity>lambdaQuery()
                .eq(WorkContactEmployeeEntity::getContactId, id)
                .eq(WorkContactEmployeeEntity::getCorpId, CorpContextHolder.getCorpId()));
        List<WorkContactEmployeeEntity> records = page.getRecords();
        List<EmployeeListByContactVO> vos = new LinkedList<>();
        records.forEach(r->{
            EmployeeListByContactVO vo = new EmployeeListByContactVO();
            BeanUtil.copyProperties(r,vo);
            //写入添加客户时间
            vo.setCreateTime(DateUtils.asString(r.getCreateTime()));
            //写入客户来源
            vo.setAddWayText(AddWayEnum.getByCode(vo.getAddWay()));
            //获取当前成员对客户备注的所有电话列表
            List<String> remarkMobiles = JSONArray.parseArray(r.getRemarkMobiles(), String.class);
            vo.setRemarkMobiles(remarkMobiles);

            //获取成员对客户打的标签
            List<Integer> contactTagIds = contactTagPivotService.list(Wrappers.<WorkContactTagPivotEntity>lambdaQuery()
                    .eq(WorkContactTagPivotEntity::getContactId, id)
                    .eq(WorkContactTagPivotEntity::getEmployeeId, vo.getEmployeeId()))
                    .stream().map(WorkContactTagPivotEntity::getContactTagId).collect(toList());
            List<String> tags = new LinkedList<>();
            if (!contactTagIds.isEmpty()){
                tags = contactTagService.list(Wrappers.<WorkContactTagEntity>lambdaQuery()
                        .eq(WorkContactTagEntity::getCorpId, CorpContextHolder.getCorpId())
                        .in(WorkContactTagEntity::getId, contactTagIds))
                        .stream().map(WorkContactTagEntity::getName).collect(toList());
            }
            vo.setTags(tags);
            //获取成员姓名
            String employeeName = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                    .eq(WorkEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                    .eq(WorkEmployeeEntity::getId, r.getEmployeeId())).getName();
            vo.setEmployeeName(employeeName);
            vos.add(vo);
        });
        page.setRecords(vos);
        return page;
    }

    @Override
    public SyncContactStatisticsVO getStatisticsData() {
        SyncContactStatisticsVO vo = new SyncContactStatisticsVO();
        vo.setContactTotalCount(0);
        vo.setCrmContactCount(0);
        vo.setCrmContactCountYesterdayAddedCount(0);
        vo.setNonBankContactCount(0);
        vo.setWxContactCount(0);
        vo.setQywxContactCount(0);
        //当前登录用户所在机构以及所有子级机构下的成员idList
        Set<Integer> employees = getEmployees(SecurityUtils.getUser().getDeptId());
        if (employees.isEmpty()) {
            return vo;
        }

        //客户去重
        List<Integer> contactId = workContactEmployeeService.list(Wrappers.<WorkContactEmployeeEntity>lambdaQuery()
                .eq(WorkContactEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                .in(WorkContactEmployeeEntity::getEmployeeId,employees))
                .stream().map(WorkContactEmployeeEntity::getContactId).collect(toList())
                .stream().distinct().collect(toList());
        //客户手机号去重
        List<String> contactMobiles = workContactEmployeeService.list(Wrappers.<WorkContactEmployeeEntity>lambdaQuery()
                .eq(WorkContactEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                .in(WorkContactEmployeeEntity::getEmployeeId, employees))
                .stream()
                .map(l -> {
                    l.setRemarkMobiles(JSONArray.parseArray(l.getRemarkMobiles()).isEmpty() ? "" : JSONArray.parseArray(l.getRemarkMobiles()).get(0).toString());
                    return l;
                })
                .filter(l -> !l.getRemarkMobiles().equals(""))
                .map(WorkContactEmployeeEntity::getRemarkMobiles)
                .distinct()
                .collect(Collectors.toList());

        if (contactId.isEmpty()) {
            return vo;
        }
        List<WorkContactEntity> contactList = this.list(new LambdaQueryWrapper<WorkContactEntity>()
                .eq(WorkContactEntity::getCorpId, CorpContextHolder.getCorpId())
                .in(WorkContactEntity::getId, contactId));
        //客户总数量
        Integer contactTotalCount = contactList.size();

        //微信客户数
        Integer wxContactCount = 0;

        //企业微信客户数
        Integer qywxContactCount = 0;
        for (WorkContactEntity contact : contactList) {
            switch (contact.getType()) {
                case 1:
                    wxContactCount += 1;
                    break;
                case 2:
                    qywxContactCount += 1;
                    break;
            }
        }

        List<String> wxUserIds = workEmployeeService.getWxEmpIdListByEmpIdList(new ArrayList<>(employees));
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE,-2);
        String dayBeforeYesterday = DateUtil.format(cal.getTime(), "yyyy-MM-dd HH:mm:ss");
        String yesterday = DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd HH:mm:ss");

        Integer dayBeforeYesterdayCount = contactEmployeeStaticsService.sumCrmContactInEmployeeIds(CorpContextHolder.getCorpId(), TenantContextHolder.getTenantId(), DateUtil.beginOfDay(DateUtil.parse(dayBeforeYesterday)), employees);
        Integer yesterdayCount = contactEmployeeStaticsService.sumCrmContactInEmployeeIds(CorpContextHolder.getCorpId(), TenantContextHolder.getTenantId(), DateUtil.beginOfDay(DateUtil.parse(yesterday)), employees);

        //CRM客户昨日新增数
        Integer crmContactCountYesterdayAddedCount = yesterdayCount - dayBeforeYesterdayCount < 0 ? 0 : yesterdayCount - dayBeforeYesterdayCount;

        //CRM客户数
        Integer crmContactCount = contactMobiles.isEmpty() ? 0 : workCustomInfoService.countInCustMgrNoAndMobile(wxUserIds,contactMobiles);

        //行外客户数 = 客户总数量 - CRM客户数
        Integer nonBankContactCount = contactTotalCount - crmContactCount;

        vo.setContactTotalCount(contactTotalCount);
        vo.setWxContactCount(wxContactCount);
        vo.setQywxContactCount(qywxContactCount);
        vo.setCrmContactCount(crmContactCount);
        vo.setNonBankContactCount(nonBankContactCount);
        vo.setCrmContactCountYesterdayAddedCount(crmContactCountYesterdayAddedCount);
        return vo;
    }

    @Override
    public List<SyncContactStatisticsTendencyVO> getContactTotalCount(SyncContactDetailsTendencyDTO dto) {
        Set<Integer> employeeIds = getEmployees(SecurityUtils.getUser().getDeptId());
        List<DateTime> hashList = getDetHashList(dto.getStartTime(), dto.getEndTime());
        List<SyncContactStatisticsTendencyVO> vos = new ArrayList<>();

        hashList.forEach(s -> {
            Integer contactTotalCount = 0;
            if (employeeIds != null && employeeIds.size() != 0) {
                contactTotalCount = workContactEmployeeService.list(Wrappers.<WorkContactEmployeeEntity>lambdaQuery()
                        .eq(WorkContactEmployeeEntity::getCorpId, CorpContextHolder.getCorpId())
                        .in(WorkContactEmployeeEntity::getEmployeeId,employeeIds)
                        .le(WorkContactEmployeeEntity::getCreateTime,DateUtil.endOfDay(s)))
                        .stream().map(WorkContactEmployeeEntity::getContactId).collect(toList())
                        .stream().distinct().collect(toList()).size();
            }

            SyncContactStatisticsTendencyVO vo = new SyncContactStatisticsTendencyVO();
            vo.setTime(s.toDateStr());
            vo.setType(dto.getType());
            vo.setNumber(contactTotalCount);
            vos.add(vo);
        });
        return vos;
    }

    @Override
    public List<SyncContactStatisticsTendencyVO> getCrmContactCount(SyncContactDetailsTendencyDTO dto) {
        List<DateTime> hashList = getDetHashList(dto.getStartTime(), dto.getEndTime());
        List<SyncContactStatisticsTendencyVO> vos = new ArrayList<>();
        Set<Integer> employeeIds = getEmployees(SecurityUtils.getUser().getDeptId());
        if (employeeIds.isEmpty()) {
            hashList.forEach(s -> {
                SyncContactStatisticsTendencyVO vo = new SyncContactStatisticsTendencyVO();
                vo.setTime(s.toDateStr());
                vo.setType(dto.getType());
                vo.setNumber(0);
            });
        } else {
            hashList.forEach(s -> {
                Integer crmContactCount = contactEmployeeStaticsService.sumCrmContactInEmployeeIds(CorpContextHolder.getCorpId(),TenantContextHolder.getTenantId(),DateUtil.beginOfDay(s),employeeIds);

                SyncContactStatisticsTendencyVO vo = new SyncContactStatisticsTendencyVO();
                vo.setTime(s.toDateStr());
                vo.setType(dto.getType());
                vo.setNumber(crmContactCount);
                vos.add(vo);
            });
        }
        return vos;
    }

    @Override
    public List<SyncContactStatisticsTendencyVO> getNonBankContactCount(SyncContactDetailsTendencyDTO dto) {
        List<DateTime> hashList = getDetHashList(dto.getStartTime(), dto.getEndTime());
        List<SyncContactStatisticsTendencyVO> vos = new ArrayList<>();
        Set<Integer> employeeIds = getEmployees(SecurityUtils.getUser().getDeptId());
        if (employeeIds.isEmpty()) {
            hashList.forEach(s -> {
                SyncContactStatisticsTendencyVO vo = new SyncContactStatisticsTendencyVO();
                vo.setTime(s.toDateStr());
                vo.setType(dto.getType());
                vo.setNumber(0);
            });
        } else {
            hashList.forEach(s -> {
                Integer nonBankContactCount = contactEmployeeStaticsService.sumNonBankContactInEmployeeIds(CorpContextHolder.getCorpId(),TenantContextHolder.getTenantId(),DateUtil.beginOfDay(s),employeeIds);

                SyncContactStatisticsTendencyVO vo = new SyncContactStatisticsTendencyVO();
                vo.setTime(s.toDateStr());
                vo.setType(dto.getType());
                vo.setNumber(nonBankContactCount);
                vos.add(vo);
            });
        }
        return vos;
    }

    @Override
    public List<SyncContactStatisticsTendencyVO> getWxContactCount(SyncContactDetailsTendencyDTO dto) {
        Set<Integer> employeeIds = getEmployees(SecurityUtils.getUser().getDeptId());
        List<DateTime> hashList = getDetHashList(dto.getStartTime(), dto.getEndTime());
        List<SyncContactStatisticsTendencyVO> vos = new ArrayList<>();

        hashList.forEach(s -> {
            Integer wxContactCount = 0;
            if (employeeIds != null && employeeIds.size() != 0) {
                wxContactCount = workContactEmployeeService.getContactCountByContactTypeAndEmployeeIds(1,employeeIds,DateUtil.endOfDay(s).toString());
            }

            SyncContactStatisticsTendencyVO vo = new SyncContactStatisticsTendencyVO();
            vo.setTime(s.toDateStr());
            vo.setType(dto.getType());
            vo.setNumber(wxContactCount);
            vos.add(vo);
        });
        return vos;
    }

    @Override
    public List<SyncContactStatisticsTendencyVO> getQywxContactCount(SyncContactDetailsTendencyDTO dto) {
        Set<Integer> employeeIds = getEmployees(SecurityUtils.getUser().getDeptId());
        List<DateTime> hashList = getDetHashList(dto.getStartTime(), dto.getEndTime());
        List<SyncContactStatisticsTendencyVO> vos = new ArrayList<>();

        hashList.forEach(s -> {
            Integer qywxContactCount = 0;
            if (employeeIds != null && employeeIds.size() != 0) {
                qywxContactCount = workContactEmployeeService.getContactCountByContactTypeAndEmployeeIds(2,employeeIds,DateUtil.endOfDay(s).toString());
            }

            SyncContactStatisticsTendencyVO vo = new SyncContactStatisticsTendencyVO();
            vo.setTime(s.toDateStr());
            vo.setType(dto.getType());
            vo.setNumber(qywxContactCount);
            vos.add(vo);
        });
        return vos;
    }

    @Override
    public IPage<ManagerViewCustomerVO> getManagerViewCustomerInfoPage(Page page, String wxUserId, String name) {
        List<ManagerViewCustomerVO> resultList = new ArrayList<>();
        //crm客户字典
        List<SysDictItem> crmDictList = remoteDictService.getCrmCustDict();
        List<ManagerViewCustomerVO> managerViewCustomerVOList = baseMapper.getManagerViewCustomerVOListByWxUserId(CorpContextHolder.getCorpId(), wxUserId, name);
//        List<String> mobiles = new ArrayList<>();
        managerViewCustomerVOList.forEach(vo->{
            //暂时设置为未认证，后续优化
            vo.setAuthenticationMark("1");
            vo.setCustNo("");
            if (JSONArray.parseArray(vo.getMobile()).isEmpty()) {
                vo.setMobile("");
                vo.setCustType(2);
            } else {
//                mobiles.add(JSONArray.parseArray(vo.getMobile()).get(0).toString());
                List<Map<String, String>> mapList = workCustomInfoService.getCustNameAndAssetsLevelByMobile(JSONArray.parseArray(vo.getMobile()).get(0).toString());
                //去除空元素
                mapList.removeIf(map->
                    CollectionUtil.isEmpty(map)
                );
                if (!mapList.isEmpty()) {
                    vo.setCustNo(mapList.get(0).get("custNo"));
                    vo.setName(mapList.get(0).get("custName"));
                    vo.setCustType(1);
                    vo.setAssetsLevel(valueToText(mapList.get(0).get("assetsLevel"), CrmDictTypeConstants.TYPE_ASSETS_LEVEL,crmDictList));
                } else {
                    vo.setCustType(2);
                }
                vo.setMobile(JSONArray.parseArray(vo.getMobile()).get(0).toString());
            }
        });
        /*
        log.debug("mobiles:" + mobiles);
        if (mobiles != null && mobiles.size() > 0) {
            List<Map<String, String>> baseMapList = workCustomInfoService.getCustNameAndAssetsLevelByMobiles(mobiles);
            managerViewCustomerVOList.forEach(vo -> {
                if (!(JSONArray.parseArray(vo.getMobile()).isEmpty())) {
                    List<Map<String, String>> mapList = baseMapList.stream().filter(s -> {
                        return s.get("mobileTel").equals(JSONArray.parseArray(vo.getMobile()).get(0).toString());
//                        String mobile = s.get("mobileTel");
//                        if (mobile.equals(JSONArray.parseArray(vo.getMobile()).get(0).toString())) {
//                            return true;
//                        }
//                        return false;
                    }).collect(Collectors.toList());
                    //去除空元素
                    mapList.removeIf(map->
                            CollectionUtil.isEmpty(map)
                    );
                    if (!mapList.isEmpty()) {
                        vo.setCustNo(mapList.get(0).get("custNo"));
                        vo.setName(mapList.get(0).get("custName"));
                        vo.setCustType(1);
                        vo.setAssetsLevel(valueToText(mapList.get(0).get("assetsLevel"), CrmDictTypeConstants.TYPE_ASSETS_LEVEL,crmDictList));
                    } else {
                        vo.setCustType(2);
                    }
                    vo.setMobile(JSONArray.parseArray(vo.getMobile()).get(0).toString());
                }
            });
        }*/

        if (!StrUtil.isBlank(name)) {
            resultList = managerViewCustomerVOList.stream().filter(vo -> vo.getName().contains(name) || vo.getMobile().equals(name) || vo.getCustNo().equals(name)).collect(Collectors.toList());
        } else {
            resultList = managerViewCustomerVOList;
        }
        return PageUtil.split(resultList, (int) page.getCurrent(), (int) page.getSize());
    }

    @Override
    public List<Map<String, String>> getMobileAndWxExternalUseridByWxUserId(String wxUserId) {
        List<Map<String, String>> mapList = baseMapper.getMobileAndWxExternalUseridByWxUserId(wxUserId);
        //去除空元素
        mapList.removeIf(map->
                CollectionUtil.isEmpty(map)
        );
        //手机号处理
        mapList.forEach(map->{
            String mobileJsonArray = map.get("mobile");
            map.put("mobile",JSONArray.parseArray(mobileJsonArray).isEmpty() ? "" : JSONArray.parseArray(mobileJsonArray).get(0).toString());
        });
        return mapList;
    }

    @Override
    public List<Map<String, String>> getNoCommunicationMapList(Integer corpId) {
        RemindCommunicationEntity communicationEntity = remindCommunicationService.getOne(Wrappers.<RemindCommunicationEntity>lambdaQuery().eq(RemindCommunicationEntity::getCorpId, corpId).orderByDesc(BaseEntity::getCreateTime).last("limit 1"));
        //未交流客户配置
        if(null==communicationEntity){
            return new ArrayList<Map<String,String>>();
        }
        List<Integer> tagIds = JSONUtil.toList(JSONUtil.parseArray(communicationEntity.getTagIds()),Integer.class);
        if (tagIds.isEmpty()) {
            return new ArrayList<Map<String,String>>();
        }
        //全部成员
        List<WorkEmployeeEntity> employeeEntities = workEmployeeService.list(new LambdaQueryWrapper<WorkEmployeeEntity>()
                .select(WorkEmployeeEntity::getId,WorkEmployeeEntity::getName)
                .eq(WorkEmployeeEntity::getCorpId,corpId));
        if(employeeEntities.size() == 0){
            return new ArrayList<Map<String,String>>();
        }
        ArrayList<Map<String, String>> noCommunicationMapList = new ArrayList<>();
        for (WorkEmployeeEntity employeeEntity : employeeEntities) {
            //该成员下符合条件的客户
            List<ContactByTagDto> contactByTagDtoList = baseMapper.getContactByEmployee(corpId, tagIds, employeeEntity.getName());
            for (ContactByTagDto dto:contactByTagDtoList){
                //聊天记录
                WorkMsgEntity workMsgEntity = workMsgMapper.countTime(dto.getWxUserId(),dto.getWxExternalUserid(),corpId);
                if(null==workMsgEntity){
                    continue;
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date nowTime =DateUtils.asDate(LocalDateTime.now());
                Date endTime = DateUtils.asDate(DateUtils.asLocalDateTime(sdf.format(new Date(Long.parseLong(workMsgEntity.getMsgTime())))));
                //未交流天数
                long between = DateUtil.between(endTime, nowTime, DateUnit.DAY);
                if(between>communicationEntity.getTime()){
                    HashMap<String, String> map = new HashMap<>();
                    map.put("wxUserId",dto.getWxUserId());
                    map.put("wxExternalUserid",dto.getWxExternalUserid());
                    map.put("msgTime",workMsgEntity.getMsgTime());
                    noCommunicationMapList.add(map);
                }
            }
        }
        List<Map<String, String>> mapList = noCommunicationMapList.stream().distinct().collect(Collectors.toList());
        return mapList;
    }


    private Map<List<WorkContactEmployeeEntity>, List<WorkContactTagPivotEntity>> getList(Map<WorkContactEntity, Map<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>>> modelMap, Integer empId, Integer contactId) {
        Map<List<WorkContactEmployeeEntity>, List<WorkContactTagPivotEntity>> map = new HashMap<>();
        List<WorkContactEmployeeEntity> contactEmployeeList = new ArrayList<>();
        List<WorkContactTagPivotEntity> contactTagPivotList = new ArrayList<>();
        for (Map.Entry<WorkContactEntity, Map<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>>> entry : modelMap.entrySet()) {
            log.info("modelMap.entrySet()为:"+modelMap.entrySet());
            for (Map.Entry<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>> aa : entry.getValue().entrySet()) {
                log.info("entry.getValue().entrySet()为："+entry.getValue().entrySet());
                for (Map.Entry<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>> bb : aa.getValue().entrySet()) {
                    log.info("aa.getValue().entrySet()为："+aa.getValue().entrySet());
                    if (contactId == null) {
                        contactId = entry.getKey().getId();
                    }
                    bb.getKey().setContactId(contactId);
                    bb.getKey().setEmployeeId(empId);
                    Map<String, Integer> tagIds = contactTagPivotService.getContactTapIdOrWxTagId(empId, contactId);
                    log.info("tagIds为："+tagIds);
                    log.info("bb.getValue().entrySet()为："+bb.getValue().entrySet());
                    for (Map.Entry<String, WorkContactTagPivotEntity> cc : bb.getValue().entrySet()) {
                        cc.getValue().setContactId(entry.getKey().getId());
                        cc.getValue().setEmployeeId(empId);
                        cc.getValue().setContactTagId(tagIds.get(cc.getKey()));
                    }
                    contactTagPivotList.addAll(bb.getValue().values().stream().filter(c -> c.getContactTagId() != null).collect(toList()));
                }
                contactEmployeeList.addAll(aa.getValue().keySet().stream().collect(toList()));
            }
        }
        map.put(contactEmployeeList, contactTagPivotList);
        return map;
    }

    /**
     * @description 回调函数--编辑企业客户事件
     * @author zhaojinjian
     * @createTime 2020/12/21 10:57
     */
    @Override
    public void editExternalContact(String externalUserid, String userId) {
        WorkEmployeeEntity employeeEntity = workEmployeeService.getWorkEmployeeInfo(userId);
        WorkContactEntity contactEntitys = workContactService.getWorkContactByWxExternalUserId(externalUserid);
        log.info("employeeEntity为："+employeeEntity);
        if (employeeEntity != null) {
            JSONArray contactUserId = new JSONArray();
            contactUserId.add(externalUserid);
            log.info("contactUserId为"+contactUserId);
            //获取微信客户详情
            Map<String, JSONObject> contactInfo = externalContactService.getExternalContactMap(contactUserId, employeeEntity.getCorpId());
            log.info("contactInfo为："+contactInfo);
            Map<WorkContactEntity, Map<String, Map<WorkContactEmployeeEntity, Map<String, WorkContactTagPivotEntity>>>> modelMap = externalContactToWorkContact(contactInfo, employeeEntity.getCorpId(), userId);
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            log.info("modelMap为："+modelMap);
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            Integer contactId = getContactId(externalUserid,employeeEntity.getCorpId());
            if (contactId != null) {
                Optional<WorkContactEntity> contactOp = modelMap.keySet().stream().findAny();
                log.info("contactOp为：" +contactOp);
                WorkContactEntity contactEntity = contactOp.get();
                log.info("contactEntity为："+contactEntity);
                if (contactEntity != null) {
                    contactEntity.setId(contactId);
                    this.updateById(contactEntity);
                    Map<List<WorkContactEmployeeEntity>, List<WorkContactTagPivotEntity>> map = getList(modelMap, employeeEntity.getId(), contactId);
                    log.info("map为："+map);
                    for (Map.Entry<List<WorkContactEmployeeEntity>, List<WorkContactTagPivotEntity>> list : map.entrySet()) {
                        //做判断不存在要新增
                        List<WorkContactEmployeeEntity> contactEmployeeEntities = list.getKey();
                        log.info("contactEmployeeEntities为："+contactEmployeeEntities);
                        List<WorkContactTagPivotEntity> contactFieldPivots = list.getValue();
                        log.info("contactFieldPivots为："+contactFieldPivots);
                        WorkContactEmployeeEntity contactEmployeeEntity = workContactEmployeeService.getWorkContactEmployeeInfo(employeeEntity.getCorpId(), employeeEntity.getId(), contactId);
                        log.info("contactEmployeeEntity为："+contactEmployeeEntity);
                        contactEmployeeEntities.get(0).setId(contactEmployeeEntity.getId());
                        if (!contactEmployeeEntities.isEmpty()) {
                            workContactEmployeeService.updateContactEmployee(contactEmployeeEntities.get(0));
                        }
                        if (!contactFieldPivots.isEmpty()) {
                            contactTagPivotService.updateContactTapPivot(contactFieldPivots);
                        }
                        
                        String format = String.format("【%s】修改了客户【%s】的信息", employeeEntity.getName(), contactEntitys.getName());
                        saveTrack(employeeEntity.getId(),contactEntitys.getId(),EventEnum.INFO,format,2, null);
                    }
                }
            }
        }
    }

    /**
     * @description 回调函数--删除企业客户事件
     * @author zhaojinjian
     * @createTime 2020/12/21 11:46
     */
    @Override
    public void deleteExternalContact(String externalUserid, String userId,String source) {
        log.info("source:"+source);
        WorkEmployeeEntity employeeEntity = workEmployeeService.getWorkEmployeeInfo(userId);
        WorkContactEntity contactEntity = workContactService.getWorkContactByWxExternalUserId(externalUserid);
        if (employeeEntity != null && contactEntity != null ) {
//            QueryWrapper<WorkContactEntity> contactWrapper = new QueryWrapper<>();
//            contactWrapper.eq("wx_external_userid", externalUserid);
//            WorkContactEntity contactEntity = new WorkContactEntity();
//            contactEntity.setDelFlag(1);
//            this.update(contactEntity, contactWrapper);

            workContactEmployeeService.deleteContactEmployee(employeeEntity.getCorpId(), employeeEntity.getId(), contactEntity.getId());
            contactTagPivotService.deleteContactTagPivot(employeeEntity.getId(), contactEntity.getId());
            String content = null;
            if (StrUtil.isBlank(source)){
                content = String.format("【%s】把【%s】从好友中删除",employeeEntity.getName() , contactEntity.getName());
            }else {
                if (source.equals("DELETE_BY_TRANSFER") || source.equals("delete_by_transfer")){
                    content = String.format("【%s】将客户【%s】转接到其他成员名下",employeeEntity.getName() , contactEntity.getName());
                }
            }
            saveTrack(employeeEntity.getId(),contactEntity.getId(),EventEnum.DE_FRIENDED,content,2, null);
            channelCodeContactStatisticsService.saveContact(employeeEntity.getCorpId());
        }
    }

    private void saveContactLoss(WorkEmployeeEntity employeeEntity, WorkContactEntity contactEntity) {
        Integer corpId = employeeEntity.getCorpId();
        Integer contactId = contactEntity.getId();
        Integer employeeId = employeeEntity.getId();
        //
        QueryWrapper<WorkContactEmployeeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("corp_id", corpId);
        wrapper.eq("contact_id", contactId);
        wrapper.eq("employee_id", employeeId);
        WorkContactEmployeeEntity contactEmployeeEntity = workContactEmployeeService.getLatest(contactId, employeeId);

        //
        ContactLossEntity entity = new ContactLossEntity();
        entity.setCorpId(corpId);
        entity.setContactName(contactEntity.getName());
        entity.setEmployeeName(employeeEntity.getName());
        entity.setContactId(contactEntity.getId());
        entity.setEmployeeId(employeeEntity.getId());
        entity.setBuildTime(contactEmployeeEntity.getCreateTime());
        entity.setLossTime(LocalDateTime.now());
        String latestTime = workMsgMapper.getLatestTime(contactEntity.getWxExternalUserid(), employeeEntity.getWxUserId());
        if (latestTime != null) {
            Long aLong = Long.valueOf(latestTime);
            Instant instant = Instant.ofEpochMilli(aLong);
            LocalDateTime of = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
            entity.setLatestChatTime(of);
        }

        entity.setContactGender(contactEntity.getGender());
        System.out.println("contactLossService>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +
                entity);
        contactLossService.save(entity);
    }

    /**
     * @description 回调函数--客户删除企业成员事件
     * @author zhaojinjian
     * @createTime 2020/12/21 11:54
     */
    @Override
    public void externalContactDeleteEmployee(String externalUserid, String userId) {
        WorkEmployeeEntity employeeEntity = workEmployeeService.getWorkEmployeeInfo(userId);
        WorkContactEntity contactEntity = workContactService.getWorkContactByWxExternalUserId(externalUserid);
        if (employeeEntity != null) {
            Integer contactId = getContactId(externalUserid,contactEntity.getCorpId());
            saveContactLoss(employeeEntity, contactEntity);
            workContactEmployeeService.deleteContactEmployee(employeeEntity.getCorpId(), employeeEntity.getId(), contactId);
            contactTagPivotService.deleteContactTagPivot(employeeEntity.getId(), contactId);
            Integer channel = null;
            String content = String.format("【%s】把【%s】从好友中删除",contactEntity.getName() , employeeEntity.getName());
            saveTrack(employeeEntity.getId(),contactEntity.getId(),EventEnum.CUSTOMER_LOSS,content,2, null);
            channelCodeContactStatisticsService.saveContact(employeeEntity.getCorpId());

        }

    }
    /**
     * @description 回调函数--用户为客户绑定企业标签事件
     * @author yushhen.qi
     * @createTime 2020/12/21 11:54
     */
    @Override
    public void tagSaveContact(String externalUserid, String userId,String name) {
        Integer channel=2;
        WorkEmployeeEntity employeeEntity = workEmployeeService.getWorkEmployeeInfo(userId);
        WorkContactEntity contactEntity = workContactService.getWorkContactByWxExternalUserId(externalUserid);
        String content = String.format("【%s】为【%s】绑定了企业标签【%s】",employeeEntity.getName() , contactEntity.getName(),name);
        saveTrack(employeeEntity.getId(),contactEntity.getId(),EventEnum.TAG,content,channel, null);
    }
    /**
     * @description 回调函数--用户为客户删除企业标签事件
     * @author yushhen.qi
     * @createTime 2020/12/21 11:54
     */
    @Override
    public void tagDeleteContact(String externalUserid, String userId, String name) {
        Integer channel=2;
        WorkEmployeeEntity employeeEntity = workEmployeeService.getWorkEmployeeInfo(userId);
        WorkContactEntity contactEntity = workContactService.getWorkContactByWxExternalUserId(externalUserid);
        String content = String.format("【%s】为【%s】删除了企业标签【%s】",employeeEntity.getName() , contactEntity.getName(),name);
        saveTrack(employeeEntity.getId(),contactEntity.getId(),EventEnum.TAG,content,channel, null);
    }
    /**
     * @description 回调函数--用户为客户添加个人标签事件
     * @author yushhen.qi
     * @createTime 2020/12/21 11:54
     */
    @Override
    public void userTagSaveContact(String externalUserid, String userId, String name) {
        Integer channel=2;
        WorkEmployeeEntity employeeEntity = workEmployeeService.getWorkEmployeeInfo(userId);
        WorkContactEntity contactEntity = workContactService.getWorkContactByWxExternalUserId(externalUserid);
        String content = String.format("【%s】为【%s】添加个人标签【%s】",employeeEntity.getName() , contactEntity.getName(),name);
        saveTrack(employeeEntity.getId(),contactEntity.getId(),EventEnum.TAG,content,channel, null);
    }
    /**
     * @description 回调函数--用户为客户删除个人标签事件
     * @author yushhen.qi
     * @createTime 2020/12/21 11:54
     */
    @Override
    public void userTagDeleteContact(String externalUserid, String userId, String name) {
        Integer channel=2;
        WorkEmployeeEntity employeeEntity = workEmployeeService.getWorkEmployeeInfo(userId);
        WorkContactEntity contactEntity = workContactService.getWorkContactByWxExternalUserId(externalUserid);
        String content = String.format("【%s】为【%s】删除个人标签【%s】",employeeEntity.getName() , contactEntity.getName(),name);
        saveTrack(employeeEntity.getId(),contactEntity.getId(),EventEnum.TAG,content,channel, null);
    }

    private Set<Integer> getEmployees(Integer deptId) {
        R r = remoteDeptService.getDeptsAndUsers(deptId);
        log.info("r:{}",r);
        Map<String, Object> data = (Map) r.getData();
        List<Integer> wxDeptIds = (List<Integer>) data.get("wxDeptIds");
        List<String> userMobiles = (List<String>) data.get("userMobiles");
        return employeeService.getEmployeeIds(wxDeptIds, userMobiles);
    }

    @SneakyThrows
    private void saveTrack(Integer employeeId, Integer contactId, Integer joinContactId) {
        Integer corpId = CorpContextHolder.getCorpId();
        //查询成员信息
        WorkEmployeeEntity employeeEntity = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                .eq(WorkEmployeeEntity::getCorpId, corpId)
                .eq(WorkEmployeeEntity::getId, employeeId),false);
        if(employeeEntity == null) {
            return;
        }
        String employeeName = employeeEntity.getName();

        //查询联系人信息
        WorkContactEntity contactEntity = contactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getCorpId, corpId)
                .eq(WorkContactEntity::getId, contactId),false);
        if(contactEntity == null) {
            return;
        }
        String contactName = contactEntity.getName();

        //查询联系人信息
        WorkContactEntity joinContactEntity = contactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getCorpId, corpId)
                .eq(WorkContactEntity::getId, joinContactId),false);
        if(joinContactEntity == null) {
            return;
        }
        String joinContactName = joinContactEntity.getName();
        if (employeeId == null || contactId == null || org.apache.commons.lang3.StringUtils.isAnyEmpty(
                employeeName,
                contactName,
                joinContactName
        )) {
            log.error("轨迹条件不满足：{}");
            return;
        }
        List<String> datas = new ArrayList<>();
        datas.add(joinContactName);
        datas.add(contactName);
        datas.add(employeeName);
        String content = String.format("【%s】通过扫描【%s】分享的一客一码添加了【%s】为客户经理", datas.toArray(new String[datas.size()]));

        //保存轨迹 channel:2-侧边栏
        contactService.saveTrack(employeeId, joinContactId, EventEnum.CREATE, content,2, corpId);

    }

    private void workRoomAutoPullIdHandle(String state, String welcomeCode, WorkEmployeeEntity employeeEntity, WorkContactEntity contactEntity) {
        //获取自动拉群id
        Integer roomAutoPullId = Integer.parseInt(state.split("-")[1]);
        //获取自动拉群详情
        WorkRoomAutoPullEntity roomAutoPullDetail = workRoomAutoPullService.getRoomAutoPullInfo(roomAutoPullId);
        log.info("roomAutoPullDetail="+roomAutoPullDetail);
        //
        if (roomAutoPullDetail != null) {
            String tags = roomAutoPullDetail.getTags();
            JSONArray tagArray = JSONArray.parseArray(tags);
            if(tagArray.toArray().length>0){
                for (int i = 0; i < tagArray.size(); i++) {
                    if(!StrUtil.isBlank(tagArray.get(i).toString())){
                        WorkContactTagPivotEntity tagPivotEntity = new WorkContactTagPivotEntity();
                        tagPivotEntity.setContactTagId(Integer.parseInt(tagArray.get(i).toString()));
                        tagPivotEntity.setEmployeeId(employeeEntity.getId());
                        tagPivotEntity.setCreateTime(LocalDateTime.now());
                        tagPivotEntity.setType(1);
                        tagPivotEntity.setContactId(contactEntity.getId());
                        log.info("contactId="+contactEntity.getId());
                        contactTagPivotService.save(tagPivotEntity);
                    }
                }
            }
            String roomJson = roomAutoPullDetail.getRooms();
            JSONArray roomJsonArray = JSON.parseArray(roomJson);
            log.info("roomJson="+roomJson);
            log.info("roomJsonArray="+roomJsonArray);
            String roomQrcodeMediaId = "";
            String roomQrcodeUrl="";
            if(roomJsonArray.toArray().length==1){
                JSONObject roomJsonObj = roomJsonArray.getJSONObject(0);
                int roomId = roomJsonObj.getIntValue("roomId");
                int maxNum = roomJsonObj.getIntValue("roomMax");
                WorkRoomEntity roomEntity = roomService.getById(roomId);
                int roomMax = roomEntity.getRoomMax();
                int count = contactRoomService.lambdaQuery()
                        .eq(WorkContactRoomEntity::getRoomId, roomEntity.getId())
                        .count();
                if (count < roomMax && count < maxNum) {
                    // 拉人中 发送此群二维码
                    File roomQrcodeFile = FilesUtil.getFileByURI(roomJsonObj.getString("roomQrcodeUrl"));
                    roomQrcodeMediaId = WxApiUtils.uploadImageToTemp(employeeEntity.getCorpId(), roomQrcodeFile);
                }else {
                    throw new CheckedException("此群已满，请新增客群！");
                }
            }else {
                for (int i = 0; i <= roomJsonArray.size()-1; i++) {
                    JSONObject roomJsonObj = roomJsonArray.getJSONObject(i);
                    int roomId = roomJsonObj.getIntValue("roomId");
                    int maxNum = roomJsonObj.getIntValue("roomMax");
                    WorkRoomEntity roomEntity = roomService.getById(roomId);
                    int roomMax = roomEntity.getRoomMax();
                    int count = contactRoomService.lambdaQuery()
                            .eq(WorkContactRoomEntity::getRoomId, roomEntity.getId())
                            .count();
                    if (count < roomMax && count < maxNum) {
                        // 拉人中 发送此群二维码
                        File roomQrcodeFile = FilesUtil.getFileByURI(roomJsonObj.getString("roomQrcodeUrl"));
                        roomQrcodeMediaId = WxApiUtils.uploadImageToTemp(employeeEntity.getCorpId(), roomQrcodeFile);
                        break;
                    }
                }
            }
            sendWelcomeMsgService.send(employeeEntity.getCorpId(), welcomeCode, roomAutoPullDetail.getLeadingWords(),roomQrcodeMediaId,contactEntity.getName());
        }
    }

    private void channelCodePreHandle(
            String state, String externalUserid, String welcomeCode, String wxCorpId,
            Map<String, JSONObject> contactInfo,
            WorkEmployeeEntity employeeEntity
    ) {
        // 获取渠道码 id
        Integer channelCodeId = Integer.parseInt(state.split("-")[1]);
        log.info("channelCodeId："+channelCodeId);
        Map<String, Object> map = channelCodeService.getWelcomeMsgMap(channelCodeId,employeeEntity.getCorpId(),externalUserid,employeeEntity.getId());
        log.info("渠道活码map："+map);
        if (map != null){
            log.info("发送渠道活码欢迎语");
            greetingServiceImpl.applyWxSendContactMessage(wxCorpId,welcomeCode,contactInfo,map);
            log.info("发送渠道活码欢迎语成功");
        }
        log.info("添加客户标签");
        channelCodeService.saveTag(employeeEntity.getCorpId(),channelCodeId,externalUserid,employeeEntity.getId());
        log.info("添加客户标签成功");

    }

    private String valueToText(String dictValue, String dictType, List<SysDictItem> crmDictList) {
        List<String> textList = crmDictList.stream()
                .filter(l -> l.getType().equals(dictType) && l.getValue().equals(dictValue))
                .map(l->l.getLabel())
                .collect(Collectors.toList());
        if (textList.isEmpty()) {
            return dictValue;
        } else {
            return textList.get(0);
        }
    }

    /**
     * 通过企业id和客户微信id查询客户
     * @param corpId
     * @param externalUserid
     * @return
     */
    private WorkContactEntity getContactByCorpIdAndExternalUserid(Integer corpId, String externalUserid) {
        return this.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getCorpId, corpId)
                .eq(WorkContactEntity::getWxExternalUserid, externalUserid));
    }

}
